diff options
Diffstat (limited to 'src/mscorlib/src/System/IO')
34 files changed, 38 insertions, 4453 deletions
diff --git a/src/mscorlib/src/System/IO/BinaryReader.cs b/src/mscorlib/src/System/IO/BinaryReader.cs index 4145a7f4f6..d973860472 100644 --- a/src/mscorlib/src/System/IO/BinaryReader.cs +++ b/src/mscorlib/src/System/IO/BinaryReader.cs @@ -23,7 +23,6 @@ namespace System.IO { using System.Diagnostics.Contracts; using System.Security; -[System.Runtime.InteropServices.ComVisible(true)] public class BinaryReader : IDisposable { private const int MaxCharBytesSize = 128; diff --git a/src/mscorlib/src/System/IO/BinaryWriter.cs b/src/mscorlib/src/System/IO/BinaryWriter.cs index f99b4d3d42..b6c562534c 100644 --- a/src/mscorlib/src/System/IO/BinaryWriter.cs +++ b/src/mscorlib/src/System/IO/BinaryWriter.cs @@ -26,7 +26,6 @@ namespace System.IO { // give unique encodings. // [Serializable] - [System.Runtime.InteropServices.ComVisible(true)] public class BinaryWriter : IDisposable { public static readonly BinaryWriter Null = new BinaryWriter(); @@ -185,7 +184,7 @@ namespace System.IO { Debug.Assert(_encoding.GetMaxByteCount(1) <= 16, "_encoding.GetMaxByteCount(1) <= 16)"); int numBytes = 0; - fixed(byte * pBytes = _buffer) { + fixed(byte * pBytes = &_buffer[0]) { numBytes = _encoder.GetBytes(&ch, 1, pBytes, _buffer.Length, flush: true); } OutStream.Write(_buffer, 0, numBytes); @@ -382,7 +381,7 @@ namespace System.IO { } fixed (char* pChars = value) { - fixed (byte* pBytes = _largeByteBuffer) + fixed (byte* pBytes = &_largeByteBuffer[0]) { byteLen = _encoder.GetBytes(pChars + charStart, charCount, pBytes, _largeByteBuffer.Length, charCount == numLeft); } diff --git a/src/mscorlib/src/System/IO/Directory.cs b/src/mscorlib/src/System/IO/Directory.cs index d6b68222cd..88a669a971 100644 --- a/src/mscorlib/src/System/IO/Directory.cs +++ b/src/mscorlib/src/System/IO/Directory.cs @@ -17,7 +17,6 @@ using System.Collections.Generic; using System.Security; -using System.Security.Permissions; using Microsoft.Win32; using Microsoft.Win32.SafeHandles; using System.Runtime.InteropServices; @@ -26,404 +25,7 @@ using System.Diagnostics.Contracts; namespace System.IO { - [ComVisible(true)] - public static class Directory { - public static DirectoryInfo GetParent(String path) - { - if (path==null) - throw new ArgumentNullException(nameof(path)); - - if (path.Length==0) - throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"), nameof(path)); - Contract.EndContractBlock(); - - string fullPath = Path.GetFullPath(path); - - string s = Path.GetDirectoryName(fullPath); - if (s==null) - return null; - return new DirectoryInfo(s); - } - - public static DirectoryInfo CreateDirectory(String path) { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty")); - Contract.EndContractBlock(); - - return InternalCreateDirectoryHelper(path); - } - - internal static DirectoryInfo InternalCreateDirectoryHelper(String path) - { - Contract.Requires(path != null); - Contract.Requires(path.Length != 0); - - String fullPath = Path.GetFullPath(path); - - InternalCreateDirectory(fullPath, path, null); - - return new DirectoryInfo(fullPath, false); - } - - internal unsafe static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj) - { - int length = fullPath.Length; - - // We need to trim the trailing slash or the code will try to create 2 directories of the same name. - if (length >= 2 && PathInternal.IsDirectorySeparator(fullPath[length - 1])) - length--; - - int lengthRoot = PathInternal.GetRootLength(fullPath); - - // For UNC paths that are only // or /// - if (length == 2 && PathInternal.IsDirectorySeparator(fullPath[1])) - throw new IOException(Environment.GetResourceString("IO.IO_CannotCreateDirectory", path)); - - // We can save a bunch of work if the directory we want to create already exists. This also - // saves us in the case where sub paths are inaccessible (due to ERROR_ACCESS_DENIED) but the - // final path is accessable and the directory already exists. For example, consider trying - // to create c:\Foo\Bar\Baz, where everything already exists but ACLS prevent access to c:\Foo - // and c:\Foo\Bar. In that case, this code will think it needs to create c:\Foo, and c:\Foo\Bar - // and fail to due so, causing an exception to be thrown. This is not what we want. - if (InternalExists(fullPath)) { - return; - } - - List<string> stackDir = new List<string>(); - - // Attempt to figure out which directories don't exist, and only - // create the ones we need. Note that InternalExists may fail due - // to Win32 ACL's preventing us from seeing a directory, and this - // isn't threadsafe. - - bool somepathexists = false; - - if (length > lengthRoot) { // Special case root (fullpath = X:\\) - int i = length-1; - while (i >= lengthRoot && !somepathexists) { - String dir = fullPath.Substring(0, i+1); - - if (!InternalExists(dir)) // Create only the ones missing - stackDir.Add(dir); - else - somepathexists = true; - - while (i > lengthRoot && fullPath[i] != Path.DirectorySeparatorChar && fullPath[i] != Path.AltDirectorySeparatorChar) i--; - i--; - } - } - - int count = stackDir.Count; - - // If we were passed a DirectorySecurity, convert it to a security - // descriptor and set it in he call to CreateDirectory. - Win32Native.SECURITY_ATTRIBUTES secAttrs = null; - - bool r = true; - int firstError = 0; - String errorString = path; - // If all the security checks succeeded create all the directories - while (stackDir.Count > 0) { - String name = stackDir[stackDir.Count - 1]; - stackDir.RemoveAt(stackDir.Count - 1); - if (PathInternal.IsDirectoryTooLong(name)) - throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong")); - r = Win32Native.CreateDirectory(name, secAttrs); - if (!r && (firstError == 0)) { - int currentError = Marshal.GetLastWin32Error(); - // While we tried to avoid creating directories that don't - // exist above, there are at least two cases that will - // cause us to see ERROR_ALREADY_EXISTS here. InternalExists - // can fail because we didn't have permission to the - // directory. Secondly, another thread or process could - // create the directory between the time we check and the - // time we try using the directory. Thirdly, it could - // fail because the target does exist, but is a file. - if (currentError != Win32Native.ERROR_ALREADY_EXISTS) - firstError = currentError; - else { - // If there's a file in this directory's place, or if we have ERROR_ACCESS_DENIED when checking if the directory already exists throw. - if (File.InternalExists(name) || (!InternalExists(name, out currentError) && currentError == Win32Native.ERROR_ACCESS_DENIED)) - { - firstError = currentError; - errorString = name; - } - } - } - } - - // We need this check to mask OS differences - // Handle CreateDirectory("X:\\foo") when X: doesn't exist. Similarly for n/w paths. - if ((count == 0) && !somepathexists) { - String root = InternalGetDirectoryRoot(fullPath); - if (!InternalExists(root)) { - // Extract the root from the passed in path again for security. - __Error.WinIOError(Win32Native.ERROR_PATH_NOT_FOUND, InternalGetDirectoryRoot(path)); - } - return; - } - - // Only throw an exception if creating the exact directory we - // wanted failed to work correctly. - if (!r && (firstError != 0)) { - __Error.WinIOError(firstError, errorString); - } - } - - - // Tests if the given path refers to an existing DirectoryInfo on disk. - // - // Your application must have Read permission to the directory's - // contents. - // - public static bool Exists(String path) - { - return InternalExistsHelper(path); - } - - internal static bool InternalExistsHelper(String path) { - try - { - if (path == null) - return false; - if (path.Length == 0) - return false; - - return InternalExists(Path.GetFullPath(path)); - } - catch (ArgumentException) { } - catch (NotSupportedException) { } // Security can throw this on ":" - catch (SecurityException) { } - catch (IOException) { } - catch (UnauthorizedAccessException) - { - Debug.Assert(false, "Ignore this assert and send a repro to Microsoft. This assert was tracking purposes only."); - } - return false; - } - - // Determine whether path describes an existing directory - // on disk, avoiding security checks. - internal static bool InternalExists(String path) { - int lastError = Win32Native.ERROR_SUCCESS; - return InternalExists(path, out lastError); - } - - // Determine whether path describes an existing directory - // on disk, avoiding security checks. - internal static bool InternalExists(String path, out int lastError) { - Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - lastError = File.FillAttributeInfo(path, ref data, false, true); - - return (lastError == 0) && (data.fileAttributes != -1) - && ((data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0); - } - - public static DateTime GetCreationTime(String path) - { - return File.GetCreationTime(path); - } - - public static DateTime GetCreationTimeUtc(String path) - { - return File.GetCreationTimeUtc(path); - } - - public static DateTime GetLastWriteTime(String path) - { - return File.GetLastWriteTime(path); - } - - public static DateTime GetLastWriteTimeUtc(String path) - { - return File.GetLastWriteTimeUtc(path); - } - - public static DateTime GetLastAccessTime(String path) - { - return File.GetLastAccessTime(path); - } - - public static DateTime GetLastAccessTimeUtc(String path) - { - return File.GetLastAccessTimeUtc(path); - } - - // Returns an array of filenames in the DirectoryInfo specified by path - public static String[] GetFiles(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.Ensures(Contract.Result<String[]>() != null); - Contract.EndContractBlock(); - - return InternalGetFiles(path, "*", SearchOption.TopDirectoryOnly); - } - - // Returns an array of Files in the current DirectoryInfo matching the - // given search pattern (ie, "*.txt"). - public static String[] GetFiles(String path, String searchPattern) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - Contract.Ensures(Contract.Result<String[]>() != null); - Contract.EndContractBlock(); - - return InternalGetFiles(path, searchPattern, SearchOption.TopDirectoryOnly); - } - - // Returns an array of Files in the current DirectoryInfo matching the - // given search pattern (ie, "*.txt") and search option - public static String[] GetFiles(String path, String searchPattern, SearchOption searchOption) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories)) - throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum")); - Contract.Ensures(Contract.Result<String[]>() != null); - Contract.EndContractBlock(); - - return InternalGetFiles(path, searchPattern, searchOption); - } - - // Returns an array of Files in the current DirectoryInfo matching the - // given search pattern (ie, "*.txt") and search option - private static String[] InternalGetFiles(String path, String searchPattern, SearchOption searchOption) - { - Contract.Requires(path != null); - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - - return InternalGetFileDirectoryNames(path, path, searchPattern, true, false, searchOption, true); - } - - internal static String[] UnsafeGetFiles(String path, String searchPattern, SearchOption searchOption) - { - Contract.Requires(path != null); - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - - return InternalGetFileDirectoryNames(path, path, searchPattern, true, false, searchOption, false); - } - - // Returns an array of Directories in the current directory. - public static String[] GetDirectories(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.Ensures(Contract.Result<String[]>() != null); - Contract.EndContractBlock(); - - return InternalGetDirectories(path, "*", SearchOption.TopDirectoryOnly); - } - - // Returns an array of Directories in the current DirectoryInfo matching the - // given search criteria (ie, "*.txt"). - public static String[] GetDirectories(String path, String searchPattern) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - Contract.Ensures(Contract.Result<String[]>() != null); - Contract.EndContractBlock(); - - return InternalGetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly); - } - - // Returns an array of Directories in the current DirectoryInfo matching the - // given search criteria (ie, "*.txt"). - public static String[] GetDirectories(String path, String searchPattern, SearchOption searchOption) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories)) - throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum")); - Contract.Ensures(Contract.Result<String[]>() != null); - Contract.EndContractBlock(); - - return InternalGetDirectories(path, searchPattern, searchOption); - } - - // Returns an array of Directories in the current DirectoryInfo matching the - // given search criteria (ie, "*.txt"). - private static String[] InternalGetDirectories(String path, String searchPattern, SearchOption searchOption) - { - Contract.Requires(path != null); - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - Contract.Ensures(Contract.Result<String[]>() != null); - - return InternalGetFileDirectoryNames(path, path, searchPattern, false, true, searchOption, true); - } - - internal static String[] UnsafeGetDirectories(String path, String searchPattern, SearchOption searchOption) - { - Contract.Requires(path != null); - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - Contract.Ensures(Contract.Result<String[]>() != null); - - return InternalGetFileDirectoryNames(path, path, searchPattern, false, true, searchOption, false); - } - - // Returns an array of strongly typed FileSystemInfo entries in the path - public static String[] GetFileSystemEntries(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.Ensures(Contract.Result<String[]>() != null); - Contract.EndContractBlock(); - - return InternalGetFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly); - } - - // Returns an array of strongly typed FileSystemInfo entries in the path with the - // given search criteria (ie, "*.txt"). We disallow .. as a part of the search criteria - public static String[] GetFileSystemEntries(String path, String searchPattern) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - Contract.Ensures(Contract.Result<String[]>() != null); - Contract.EndContractBlock(); - - return InternalGetFileSystemEntries(path, searchPattern, SearchOption.TopDirectoryOnly); - } - - // Returns an array of strongly typed FileSystemInfo entries in the path with the - // given search criteria (ie, "*.txt"). We disallow .. as a part of the search criteria - public static String[] GetFileSystemEntries(String path, String searchPattern, SearchOption searchOption) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories)) - throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum")); - Contract.Ensures(Contract.Result<String[]>() != null); - Contract.EndContractBlock(); - - return InternalGetFileSystemEntries(path, searchPattern, searchOption); - } - - private static String[] InternalGetFileSystemEntries(String path, String searchPattern, SearchOption searchOption) - { - Contract.Requires(path != null); - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - - return InternalGetFileDirectoryNames(path, path, searchPattern, true, true, searchOption, true); - } + internal static class Directory { // Private class that holds search data that is passed around // in the heap based stack recursion @@ -445,90 +47,7 @@ namespace System.IO public readonly SearchOption searchOption; } - - // Returns fully qualified user path of dirs/files that matches the search parameters. - // For recursive search this method will search through all the sub dirs and execute - // the given search criteria against every dir. - // For all the dirs/files returned, it will then demand path discovery permission for - // their parent folders (it will avoid duplicate permission checks) - internal static String[] InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, bool includeFiles, bool includeDirs, SearchOption searchOption, bool checkHost) - { - Contract.Requires(path != null); - Contract.Requires(userPathOriginal != null); - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - - IEnumerable<String> enble = FileSystemEnumerableFactory.CreateFileNameIterator( - path, userPathOriginal, searchPattern, - includeFiles, includeDirs, searchOption, checkHost); - List<String> fileList = new List<String>(enble); - return fileList.ToArray(); - } - - public static IEnumerable<String> EnumerateDirectories(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - - return InternalEnumerateDirectories(path, "*", SearchOption.TopDirectoryOnly); - } - - public static IEnumerable<String> EnumerateDirectories(String path, String searchPattern) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - Contract.EndContractBlock(); - - return InternalEnumerateDirectories(path, searchPattern, SearchOption.TopDirectoryOnly); - } - - public static IEnumerable<String> EnumerateDirectories(String path, String searchPattern, SearchOption searchOption) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories)) - throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum")); - Contract.EndContractBlock(); - - return InternalEnumerateDirectories(path, searchPattern, searchOption); - } - - private static IEnumerable<String> InternalEnumerateDirectories(String path, String searchPattern, SearchOption searchOption) - { - Contract.Requires(path != null); - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - - return EnumerateFileSystemNames(path, searchPattern, searchOption, false, true); - } - - public static IEnumerable<String> EnumerateFiles(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.Ensures(Contract.Result<IEnumerable<String>>() != null); - Contract.EndContractBlock(); - - return InternalEnumerateFiles(path, "*", SearchOption.TopDirectoryOnly); - } - - public static IEnumerable<String> EnumerateFiles(String path, String searchPattern) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - Contract.Ensures(Contract.Result<IEnumerable<String>>() != null); - Contract.EndContractBlock(); - - return InternalEnumerateFiles(path, searchPattern, SearchOption.TopDirectoryOnly); - } - +#if PLATFORM_UNIX public static IEnumerable<String> EnumerateFiles(String path, String searchPattern, SearchOption searchOption) { if (path == null) @@ -553,52 +72,6 @@ namespace System.IO return EnumerateFileSystemNames(path, searchPattern, searchOption, true, false); } - public static IEnumerable<String> EnumerateFileSystemEntries(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.Ensures(Contract.Result<IEnumerable<String>>() != null); - Contract.EndContractBlock(); - - return InternalEnumerateFileSystemEntries(path, "*", SearchOption.TopDirectoryOnly); - } - - public static IEnumerable<String> EnumerateFileSystemEntries(String path, String searchPattern) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - Contract.Ensures(Contract.Result<IEnumerable<String>>() != null); - Contract.EndContractBlock(); - - return InternalEnumerateFileSystemEntries(path, searchPattern, SearchOption.TopDirectoryOnly); - } - - public static IEnumerable<String> EnumerateFileSystemEntries(String path, String searchPattern, SearchOption searchOption) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories)) - throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum")); - Contract.Ensures(Contract.Result<IEnumerable<String>>() != null); - Contract.EndContractBlock(); - - return InternalEnumerateFileSystemEntries(path, searchPattern, searchOption); - } - - private static IEnumerable<String> InternalEnumerateFileSystemEntries(String path, String searchPattern, SearchOption searchOption) - { - Contract.Requires(path != null); - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - Contract.Ensures(Contract.Result<IEnumerable<String>>() != null); - - return EnumerateFileSystemNames(path, searchPattern, searchOption, true, true); - } - private static IEnumerable<String> EnumerateFileSystemNames(String path, String searchPattern, SearchOption searchOption, bool includeFiles, bool includeDirs) { @@ -610,60 +83,14 @@ namespace System.IO return FileSystemEnumerableFactory.CreateFileNameIterator(path, path, searchPattern, includeFiles, includeDirs, searchOption, true); } - - // Retrieves the names of the logical drives on this machine in the - // form "C:\". - // - // Your application must have System Info permission. - // - public static String[] GetLogicalDrives() - { - Contract.Ensures(Contract.Result<String[]>() != null); - -#pragma warning disable 618 - new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); -#pragma warning restore 618 - - int drives = Win32Native.GetLogicalDrives(); - if (drives==0) - __Error.WinIOError(); - uint d = (uint)drives; - int count = 0; - while (d != 0) { - if (((int)d & 1) != 0) count++; - d >>= 1; - } - String[] result = new String[count]; - char[] root = new char[] {'A', ':', '\\'}; - d = (uint)drives; - count = 0; - while (d != 0) { - if (((int)d & 1) != 0) { - result[count++] = new String(root); - } - d >>= 1; - root[0]++; - } - return result; - } - - public static String GetDirectoryRoot(String path) { - if (path==null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - - string fullPath = Path.GetFullPath(path); - string root = fullPath.Substring(0, PathInternal.GetRootLength(fullPath)); - - return root; - } +#endif // PLATFORM_UNIX internal static String InternalGetDirectoryRoot(String path) { if (path == null) return null; return path.Substring(0, PathInternal.GetRootLength(path)); } - /*===============================CurrentDirectory=============================== + /*===============================CurrentDirectory=============================== **Action: Provides a getter and setter for the current directory. The original ** current DirectoryInfo is the one from which the process was started. **Returns: The current DirectoryInfo (from the getter). Void from the setter. @@ -673,20 +100,21 @@ namespace System.IO public static String GetCurrentDirectory() { // Start with a buffer the size of MAX_PATH - using (StringBuffer buffer = new StringBuffer(260)) + StringBuffer buffer = new StringBuffer(260); + try { uint result = 0; - while ((result = Win32Native.GetCurrentDirectoryW(buffer.CharCapacity, buffer.GetHandle())) > buffer.CharCapacity) + while ((result = Win32Native.GetCurrentDirectoryW((uint)buffer.Capacity, buffer.UnderlyingArray)) > buffer.Capacity) { // Reported size is greater than the buffer size. Increase the capacity. // The size returned includes the null only if more space is needed (this case). - buffer.EnsureCharCapacity(result); + buffer.EnsureCapacity(checked((int)result)); } if (result == 0) __Error.WinIOError(); - buffer.Length = result; + buffer.Length = (int)result; #if !PLATFORM_UNIX if (buffer.Contains('~')) @@ -695,12 +123,16 @@ namespace System.IO return buffer.ToString(); } + finally + { + buffer.Free(); + } } public static void SetCurrentDirectory(String path) { if (path==null) - throw new ArgumentNullException("value"); + throw new ArgumentNullException(nameof(path)); if (path.Length==0) throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty")); if (path.Length >= Path.MaxPath) @@ -718,216 +150,6 @@ namespace System.IO __Error.WinIOError(errorCode, fulldestDirName); } } - - public static void Move(String sourceDirName,String destDirName) - { - if (sourceDirName==null) - throw new ArgumentNullException(nameof(sourceDirName)); - if (sourceDirName.Length==0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceDirName)); - if (destDirName==null) - throw new ArgumentNullException(nameof(destDirName)); - if (destDirName.Length==0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destDirName)); - - String sourcePath = Path.GetFullPath(sourceDirName); - String destPath = Path.GetFullPath(destDirName); - - if (String.Compare(sourcePath, destPath, StringComparison.OrdinalIgnoreCase) == 0) - throw new IOException(Environment.GetResourceString("IO.IO_SourceDestMustBeDifferent")); - - String sourceRoot = Path.GetPathRoot(sourcePath); - String destinationRoot = Path.GetPathRoot(destPath); - if (String.Compare(sourceRoot, destinationRoot, StringComparison.OrdinalIgnoreCase) != 0) - throw new IOException(Environment.GetResourceString("IO.IO_SourceDestMustHaveSameRoot")); - - if (!Win32Native.MoveFile(sourceDirName, destDirName)) - { - int hr = Marshal.GetLastWin32Error(); - if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // Source dir not found - { - hr = Win32Native.ERROR_PATH_NOT_FOUND; - __Error.WinIOError(hr, sourcePath); - } - // This check was originally put in for Win9x (unfortunately without special casing it to be for Win9x only). We can't change the NT codepath now for backcomp reasons. - if (hr == Win32Native.ERROR_ACCESS_DENIED) // WinNT throws IOException. This check is for Win9x. We can't change it for backcomp. - throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", sourceDirName), Win32Native.MakeHRFromErrorCode(hr)); - __Error.WinIOError(hr, String.Empty); - } - } - - public static void Delete(String path) - { - String fullPath = Path.GetFullPath(path); - Delete(fullPath, path, false); - } - - public static void Delete(String path, bool recursive) - { - String fullPath = Path.GetFullPath(path); - Delete(fullPath, path, recursive); - } - - // Called from DirectoryInfo as well. FullPath is fully qualified, - // while the user path is used for feedback in exceptions. - internal static void Delete(String fullPath, String userPath, bool recursive) - { - // Do not recursively delete through reparse points. Perhaps in a - // future version we will add a new flag to control this behavior, - // but for now we're much safer if we err on the conservative side. - // This applies to symbolic links and mount points. - Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - int dataInitialised = File.FillAttributeInfo(fullPath, ref data, false, true); - if (dataInitialised != 0) { - // Ensure we throw a DirectoryNotFoundException. - if (dataInitialised == Win32Native.ERROR_FILE_NOT_FOUND) - dataInitialised = Win32Native.ERROR_PATH_NOT_FOUND; - __Error.WinIOError(dataInitialised, fullPath); - } - - if (((FileAttributes)data.fileAttributes & FileAttributes.ReparsePoint) != 0) - recursive = false; - - DeleteHelper(fullPath, userPath, recursive, true); - } - - // Note that fullPath is fully qualified, while userPath may be relative. - private static void DeleteHelper(String fullPath, String userPath, bool recursive, bool throwOnTopLevelDirectoryNotFound) - { - bool r; - int hr; - Exception ex = null; - - // Do not recursively delete through reparse points. Perhaps in a - // future version we will add a new flag to control this behavior, - // but for now we're much safer if we err on the conservative side. - // This applies to symbolic links and mount points. - // Note the logic to check whether fullPath is a reparse point is - // in Delete(String, String, bool), and will set "recursive" to false. - // Note that Win32's DeleteFile and RemoveDirectory will just delete - // the reparse point itself. - - if (recursive) { - Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA(); - - // Open a Find handle - using (SafeFindHandle hnd = Win32Native.FindFirstFile(fullPath + Path.DirectorySeparatorChar + "*", data)) { - if (hnd.IsInvalid) { - hr = Marshal.GetLastWin32Error(); - __Error.WinIOError(hr, fullPath); - } - - do { - bool isDir = (0!=(data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY)); - if (isDir) { - // Skip ".", "..". - if (data.cFileName.Equals(".") || data.cFileName.Equals("..")) - continue; - - // Recurse for all directories, unless they are - // reparse points. Do not follow mount points nor - // symbolic links, but do delete the reparse point - // itself. - bool shouldRecurse = (0 == (data.dwFileAttributes & (int) FileAttributes.ReparsePoint)); - if (shouldRecurse) { - String newFullPath = Path.Combine(fullPath, data.cFileName); - String newUserPath = Path.Combine(userPath, data.cFileName); - try { - DeleteHelper(newFullPath, newUserPath, recursive, false); - } - catch(Exception e) { - if (ex == null) { - ex = e; - } - } - } - else { - // Check to see if this is a mount point, and - // unmount it. - if (data.dwReserved0 == Win32Native.IO_REPARSE_TAG_MOUNT_POINT) { - // Use full path plus a trailing '\' - String mountPoint = Path.Combine(fullPath, data.cFileName + Path.DirectorySeparatorChar); - r = Win32Native.DeleteVolumeMountPoint(mountPoint); - if (!r) { - hr = Marshal.GetLastWin32Error(); - if (hr != Win32Native.ERROR_PATH_NOT_FOUND) { - try { - __Error.WinIOError(hr, data.cFileName); - } - catch(Exception e) { - if (ex == null) { - ex = e; - } - } - } - } - } - - // RemoveDirectory on a symbolic link will - // remove the link itself. - String reparsePoint = Path.Combine(fullPath, data.cFileName); - r = Win32Native.RemoveDirectory(reparsePoint); - if (!r) { - hr = Marshal.GetLastWin32Error(); - if (hr != Win32Native.ERROR_PATH_NOT_FOUND) { - try { - __Error.WinIOError(hr, data.cFileName); - } - catch(Exception e) { - if (ex == null) { - ex = e; - } - } - } - } - } - } - else { - String fileName = Path.Combine(fullPath, data.cFileName); - r = Win32Native.DeleteFile(fileName); - if (!r) { - hr = Marshal.GetLastWin32Error(); - if (hr != Win32Native.ERROR_FILE_NOT_FOUND) { - try { - __Error.WinIOError(hr, data.cFileName); - } - catch (Exception e) { - if (ex == null) { - ex = e; - } - } - } - } - } - } while (Win32Native.FindNextFile(hnd, data)); - // Make sure we quit with a sensible error. - hr = Marshal.GetLastWin32Error(); - } - - if (ex != null) - throw ex; - if (hr!=0 && hr!=Win32Native.ERROR_NO_MORE_FILES) - __Error.WinIOError(hr, userPath); - } - - r = Win32Native.RemoveDirectory(fullPath); - - if (!r) { - hr = Marshal.GetLastWin32Error(); - if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // A dubious error code. - hr = Win32Native.ERROR_PATH_NOT_FOUND; - // This check was originally put in for Win9x (unfortunately without special casing it to be for Win9x only). We can't change the NT codepath now for backcomp reasons. - if (hr == Win32Native.ERROR_ACCESS_DENIED) - throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", userPath)); - - // don't throw the DirectoryNotFoundException since this is a subdir and there could be a race condition - // between two Directory.Delete callers - if (hr == Win32Native.ERROR_PATH_NOT_FOUND && !throwOnTopLevelDirectoryNotFound) - return; - - __Error.WinIOError(hr, fullPath); - } - } } } diff --git a/src/mscorlib/src/System/IO/DirectoryInfo.cs b/src/mscorlib/src/System/IO/DirectoryInfo.cs deleted file mode 100644 index c4c350d245..0000000000 --- a/src/mscorlib/src/System/IO/DirectoryInfo.cs +++ /dev/null @@ -1,511 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/*============================================================ -** -** -** -** -** -** Purpose: Exposes routines for enumerating through a -** directory. -** -** April 11,2000 -** -===========================================================*/ - -using System.Collections.Generic; -using Microsoft.Win32; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Runtime.Versioning; -using System.Diagnostics; -using System.Diagnostics.Contracts; - -namespace System.IO -{ - [Serializable] - [ComVisible(true)] - public sealed class DirectoryInfo : FileSystemInfo - { - // Migrating InheritanceDemands requires this default ctor, so we can annotate it. - private DirectoryInfo(){} - - public DirectoryInfo(String path) - { - if (path==null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - - Init(path); - } - - private void Init(String path) - { - // Special case "<DriveLetter>:" to point to "<CurrentDirectory>" instead - if ((path.Length == 2) && (path[1] == ':')) - { - OriginalPath = "."; - } - else - { - OriginalPath = path; - } - - FullPath = Path.GetFullPath(path); ; - DisplayPath = GetDisplayName(OriginalPath, FullPath); - } - - internal DirectoryInfo(String fullPath, bool junk) - { - Debug.Assert(PathInternal.GetRootLength(fullPath) > 0, "fullPath must be fully qualified!"); - // Fast path when we know a DirectoryInfo exists. - OriginalPath = Path.GetFileName(fullPath); - - FullPath = fullPath; - DisplayPath = GetDisplayName(OriginalPath, FullPath); - } - - private DirectoryInfo(SerializationInfo info, StreamingContext context) : base(info, context) - { - DisplayPath = GetDisplayName(OriginalPath, FullPath); - } - - public override String Name - { - get - { - // DisplayPath is dir name for coreclr - return DisplayPath; - } - } - - public DirectoryInfo Parent { - get { - String parentName; - // FullPath might be either "c:\bar" or "c:\bar\". Handle - // those cases, as well as avoiding mangling "c:\". - String s = FullPath; - if (s.Length > 3 && s.EndsWith(Path.DirectorySeparatorChar)) - s = FullPath.Substring(0, FullPath.Length - 1); - parentName = Path.GetDirectoryName(s); - if (parentName==null) - return null; - - return new DirectoryInfo(parentName, false); - } - } - - public DirectoryInfo CreateSubdirectory(String path) { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - - return CreateSubdirectory(path, null); - } - - public DirectoryInfo CreateSubdirectory(String path, Object directorySecurity) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - - return CreateSubdirectoryHelper(path, directorySecurity); - } - - private DirectoryInfo CreateSubdirectoryHelper(String path, Object directorySecurity) - { - Contract.Requires(path != null); - - String newDirs = Path.Combine(FullPath, path); - String fullPath = Path.GetFullPath(newDirs); - - if (0!=String.Compare(FullPath,0,fullPath,0, FullPath.Length,StringComparison.OrdinalIgnoreCase)) { - String displayPath = __Error.GetDisplayablePath(DisplayPath, false); - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSubPath", path, displayPath)); - } - - Directory.InternalCreateDirectory(fullPath, path, directorySecurity); - - // Check for read permission to directory we hand back by calling this constructor. - return new DirectoryInfo(fullPath); - } - - public void Create() - { - Directory.InternalCreateDirectory(FullPath, OriginalPath, null); - } - - // Tests if the given path refers to an existing DirectoryInfo on disk. - public override bool Exists { - get - { - try - { - if (_dataInitialised == -1) - Refresh(); - if (_dataInitialised != 0) // Refresh was unable to initialise the data - return false; - return _data.fileAttributes != -1 && (_data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0; - } - catch - { - return false; - } - } - } - - // Returns an array of Files in the current DirectoryInfo matching the - // given search criteria (ie, "*.txt"). - public FileInfo[] GetFiles(String searchPattern) - { - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - Contract.EndContractBlock(); - - return InternalGetFiles(searchPattern, SearchOption.TopDirectoryOnly); - } - - // Returns an array of Files in the current DirectoryInfo matching the - // given search criteria (ie, "*.txt"). - public FileInfo[] GetFiles(String searchPattern, SearchOption searchOption) - { - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories)) - throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum")); - Contract.EndContractBlock(); - - return InternalGetFiles(searchPattern, searchOption); - } - - // Returns an array of Files in the current DirectoryInfo matching the - // given search criteria (ie, "*.txt"). - private FileInfo[] InternalGetFiles(String searchPattern, SearchOption searchOption) - { - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - - IEnumerable<FileInfo> enble = FileSystemEnumerableFactory.CreateFileInfoIterator(FullPath, OriginalPath, searchPattern, searchOption); - List<FileInfo> fileList = new List<FileInfo>(enble); - return fileList.ToArray(); - } - - // Returns an array of Files in the DirectoryInfo specified by path - public FileInfo[] GetFiles() - { - return InternalGetFiles("*", SearchOption.TopDirectoryOnly); - } - - // Returns an array of Directories in the current directory. - public DirectoryInfo[] GetDirectories() - { - return InternalGetDirectories("*", SearchOption.TopDirectoryOnly); - } - - // Returns an array of strongly typed FileSystemInfo entries in the path with the - // given search criteria (ie, "*.txt"). - public FileSystemInfo[] GetFileSystemInfos(String searchPattern) - { - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - Contract.EndContractBlock(); - - return InternalGetFileSystemInfos(searchPattern, SearchOption.TopDirectoryOnly); - } - - // Returns an array of strongly typed FileSystemInfo entries in the path with the - // given search criteria (ie, "*.txt"). - public FileSystemInfo[] GetFileSystemInfos(String searchPattern, SearchOption searchOption) - { - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories)) - throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum")); - Contract.EndContractBlock(); - - return InternalGetFileSystemInfos(searchPattern, searchOption); - } - - // Returns an array of strongly typed FileSystemInfo entries in the path with the - // given search criteria (ie, "*.txt"). - private FileSystemInfo[] InternalGetFileSystemInfos(String searchPattern, SearchOption searchOption) - { - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - - IEnumerable<FileSystemInfo> enble = FileSystemEnumerableFactory.CreateFileSystemInfoIterator(FullPath, OriginalPath, searchPattern, searchOption); - List<FileSystemInfo> fileList = new List<FileSystemInfo>(enble); - return fileList.ToArray(); - } - - // Returns an array of strongly typed FileSystemInfo entries which will contain a listing - // of all the files and directories. - public FileSystemInfo[] GetFileSystemInfos() - { - return InternalGetFileSystemInfos("*", SearchOption.TopDirectoryOnly); - } - - // Returns an array of Directories in the current DirectoryInfo matching the - // given search criteria (ie, "System*" could match the System & System32 - // directories). - public DirectoryInfo[] GetDirectories(String searchPattern) - { - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - Contract.EndContractBlock(); - - return InternalGetDirectories(searchPattern, SearchOption.TopDirectoryOnly); - } - - // Returns an array of Directories in the current DirectoryInfo matching the - // given search criteria (ie, "System*" could match the System & System32 - // directories). - public DirectoryInfo[] GetDirectories(String searchPattern, SearchOption searchOption) - { - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories)) - throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum")); - Contract.EndContractBlock(); - - return InternalGetDirectories(searchPattern, searchOption); - } - - // Returns an array of Directories in the current DirectoryInfo matching the - // given search criteria (ie, "System*" could match the System & System32 - // directories). - private DirectoryInfo[] InternalGetDirectories(String searchPattern, SearchOption searchOption) - { - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - - IEnumerable<DirectoryInfo> enble = FileSystemEnumerableFactory.CreateDirectoryInfoIterator(FullPath, OriginalPath, searchPattern, searchOption); - List<DirectoryInfo> fileList = new List<DirectoryInfo>(enble); - return fileList.ToArray(); - } - - public IEnumerable<DirectoryInfo> EnumerateDirectories() - { - return InternalEnumerateDirectories("*", SearchOption.TopDirectoryOnly); - } - - public IEnumerable<DirectoryInfo> EnumerateDirectories(String searchPattern) - { - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - Contract.EndContractBlock(); - - return InternalEnumerateDirectories(searchPattern, SearchOption.TopDirectoryOnly); - } - - public IEnumerable<DirectoryInfo> EnumerateDirectories(String searchPattern, SearchOption searchOption) - { - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories)) - throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum")); - Contract.EndContractBlock(); - - return InternalEnumerateDirectories(searchPattern, searchOption); - } - - private IEnumerable<DirectoryInfo> InternalEnumerateDirectories(String searchPattern, SearchOption searchOption) - { - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - - return FileSystemEnumerableFactory.CreateDirectoryInfoIterator(FullPath, OriginalPath, searchPattern, searchOption); - } - - public IEnumerable<FileInfo> EnumerateFiles() - { - return InternalEnumerateFiles("*", SearchOption.TopDirectoryOnly); - } - - public IEnumerable<FileInfo> EnumerateFiles(String searchPattern) - { - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - Contract.EndContractBlock(); - - return InternalEnumerateFiles(searchPattern, SearchOption.TopDirectoryOnly); - } - - public IEnumerable<FileInfo> EnumerateFiles(String searchPattern, SearchOption searchOption) - { - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories)) - throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum")); - Contract.EndContractBlock(); - - return InternalEnumerateFiles(searchPattern, searchOption); - } - - private IEnumerable<FileInfo> InternalEnumerateFiles(String searchPattern, SearchOption searchOption) - { - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - - return FileSystemEnumerableFactory.CreateFileInfoIterator(FullPath, OriginalPath, searchPattern, searchOption); - } - - public IEnumerable<FileSystemInfo> EnumerateFileSystemInfos() - { - return InternalEnumerateFileSystemInfos("*", SearchOption.TopDirectoryOnly); - } - - public IEnumerable<FileSystemInfo> EnumerateFileSystemInfos(String searchPattern) - { - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - Contract.EndContractBlock(); - - return InternalEnumerateFileSystemInfos(searchPattern, SearchOption.TopDirectoryOnly); - } - - public IEnumerable<FileSystemInfo> EnumerateFileSystemInfos(String searchPattern, SearchOption searchOption) - { - if (searchPattern == null) - throw new ArgumentNullException(nameof(searchPattern)); - if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories)) - throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum")); - Contract.EndContractBlock(); - - return InternalEnumerateFileSystemInfos(searchPattern, searchOption); - } - - private IEnumerable<FileSystemInfo> InternalEnumerateFileSystemInfos(String searchPattern, SearchOption searchOption) - { - Contract.Requires(searchPattern != null); - Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); - - return FileSystemEnumerableFactory.CreateFileSystemInfoIterator(FullPath, OriginalPath, searchPattern, searchOption); - } - - // Returns the root portion of the given path. The resulting string - // consists of those rightmost characters of the path that constitute the - // root of the path. Possible patterns for the resulting string are: An - // empty string (a relative path on the current drive), "\" (an absolute - // path on the current drive), "X:" (a relative path on a given drive, - // where X is the drive letter), "X:\" (an absolute path on a given drive), - // and "\\server\share" (a UNC path for a given server and share name). - // The resulting string is null if path is null. - public DirectoryInfo Root { - get - { - int rootLength = PathInternal.GetRootLength(FullPath); - String rootPath = FullPath.Substring(0, rootLength); - - return new DirectoryInfo(rootPath); - } - } - - public void MoveTo(String destDirName) { - if (destDirName==null) - throw new ArgumentNullException(nameof(destDirName)); - if (destDirName.Length==0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destDirName)); - Contract.EndContractBlock(); - - String fullDestDirName = Path.GetFullPath(destDirName); - if (!fullDestDirName.EndsWith(Path.DirectorySeparatorChar)) - fullDestDirName = fullDestDirName + Path.DirectorySeparatorChar; - - String fullSourcePath; - if (FullPath.EndsWith(Path.DirectorySeparatorChar)) - fullSourcePath = FullPath; - else - fullSourcePath = FullPath + Path.DirectorySeparatorChar; - - if (String.Compare(fullSourcePath, fullDestDirName, StringComparison.OrdinalIgnoreCase) == 0) - throw new IOException(Environment.GetResourceString("IO.IO_SourceDestMustBeDifferent")); - - String sourceRoot = Path.GetPathRoot(fullSourcePath); - String destinationRoot = Path.GetPathRoot(fullDestDirName); - - if (String.Compare(sourceRoot, destinationRoot, StringComparison.OrdinalIgnoreCase) != 0) - throw new IOException(Environment.GetResourceString("IO.IO_SourceDestMustHaveSameRoot")); - - if (!Win32Native.MoveFile(FullPath, destDirName)) - { - int hr = Marshal.GetLastWin32Error(); - if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // A dubious error code - { - hr = Win32Native.ERROR_PATH_NOT_FOUND; - __Error.WinIOError(hr, DisplayPath); - } - - if (hr == Win32Native.ERROR_ACCESS_DENIED) // We did this for Win9x. We can't change it for backcomp. - throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", DisplayPath)); - - __Error.WinIOError(hr,String.Empty); - } - FullPath = fullDestDirName; - OriginalPath = destDirName; - DisplayPath = GetDisplayName(OriginalPath, FullPath); - - // Flush any cached information about the directory. - _dataInitialised = -1; - } - - public override void Delete() - { - Directory.Delete(FullPath, OriginalPath, false); - } - - public void Delete(bool recursive) - { - Directory.Delete(FullPath, OriginalPath, recursive); - } - - // Returns the fully qualified path - public override String ToString() - { - return DisplayPath; - } - - private static String GetDisplayName(String originalPath, String fullPath) - { - Debug.Assert(originalPath != null); - Debug.Assert(fullPath != null); - - String displayName = ""; - - // Special case "<DriveLetter>:" to point to "<CurrentDirectory>" instead - if ((originalPath.Length == 2) && (originalPath[1] == ':')) - { - displayName = "."; - } - else - { - displayName = GetDirName(fullPath); - } - return displayName; - } - - private static String GetDirName(String fullPath) - { - Debug.Assert(fullPath != null); - - String dirName = null; - if (fullPath.Length > 3) - { - String s = fullPath; - if (fullPath.EndsWith(Path.DirectorySeparatorChar)) - { - s = fullPath.Substring(0, fullPath.Length - 1); - } - dirName = Path.GetFileName(s); - } - else - { - dirName = fullPath; // For rooted paths, like "c:\" - } - return dirName; - } - } -} - diff --git a/src/mscorlib/src/System/IO/DirectoryNotFoundException.cs b/src/mscorlib/src/System/IO/DirectoryNotFoundException.cs index 09d7e7d4e7..21211a61e7 100644 --- a/src/mscorlib/src/System/IO/DirectoryNotFoundException.cs +++ b/src/mscorlib/src/System/IO/DirectoryNotFoundException.cs @@ -23,7 +23,6 @@ namespace System.IO { * and STG_E_PATHNOTFOUND (0x80030003). */ [Serializable] - [System.Runtime.InteropServices.ComVisible(true)] public class DirectoryNotFoundException : IOException { public DirectoryNotFoundException() : base(Environment.GetResourceString("Arg_DirectoryNotFoundException")) { diff --git a/src/mscorlib/src/System/IO/DriveNotFoundException.cs b/src/mscorlib/src/System/IO/DriveNotFoundException.cs index 04155bcc0e..f0245a8b28 100644 --- a/src/mscorlib/src/System/IO/DriveNotFoundException.cs +++ b/src/mscorlib/src/System/IO/DriveNotFoundException.cs @@ -17,8 +17,7 @@ namespace System.IO { //Thrown when trying to access a drive that is not availabe. [Serializable] - [System.Runtime.InteropServices.ComVisible(true)] - public class DriveNotFoundException : IOException { + internal class DriveNotFoundException : IOException { public DriveNotFoundException() : base(Environment.GetResourceString("Arg_DriveNotFoundException")) { SetErrorCode(__HResults.COR_E_DIRECTORYNOTFOUND); @@ -28,11 +27,6 @@ namespace System.IO { : base(message) { SetErrorCode(__HResults.COR_E_DIRECTORYNOTFOUND); } - - public DriveNotFoundException(String message, Exception innerException) - : base(message, innerException) { - SetErrorCode(__HResults.COR_E_DIRECTORYNOTFOUND); - } protected DriveNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/mscorlib/src/System/IO/EndOfStreamException.cs b/src/mscorlib/src/System/IO/EndOfStreamException.cs index 60f5109a0f..558c792a9e 100644 --- a/src/mscorlib/src/System/IO/EndOfStreamException.cs +++ b/src/mscorlib/src/System/IO/EndOfStreamException.cs @@ -18,7 +18,6 @@ using System.Runtime.Serialization; namespace System.IO { [Serializable] - [System.Runtime.InteropServices.ComVisible(true)] public class EndOfStreamException : IOException { public EndOfStreamException() diff --git a/src/mscorlib/src/System/IO/File.cs b/src/mscorlib/src/System/IO/File.cs index 9f89f81a91..7cc3f431a9 100644 --- a/src/mscorlib/src/System/IO/File.cs +++ b/src/mscorlib/src/System/IO/File.cs @@ -14,7 +14,6 @@ ** ===========================================================*/ -using System.Security.Permissions; using Win32Native = Microsoft.Win32.Win32Native; using System.Runtime.InteropServices; using System.Security; @@ -28,155 +27,13 @@ namespace System.IO { // Class for creating FileStream objects, and some basic file management // routines such as Delete, etc. - [ComVisible(true)] - public static class File + internal static class File { private const int ERROR_INVALID_PARAMETER = 87; internal const int GENERIC_READ = unchecked((int)0x80000000); private const int GetFileExInfoStandard = 0; - public static StreamReader OpenText(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - return new StreamReader(path); - } - - public static StreamWriter CreateText(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - return new StreamWriter(path,false); - } - - public static StreamWriter AppendText(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - return new StreamWriter(path,true); - } - - - // Copies an existing file to a new file. An exception is raised if the - // destination file already exists. Use the - // Copy(String, String, boolean) method to allow - // overwriting an existing file. - public static void Copy(String sourceFileName, String destFileName) { - if (sourceFileName == null) - throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName")); - if (destFileName == null) - throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName")); - if (sourceFileName.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceFileName)); - if (destFileName.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName)); - Contract.EndContractBlock(); - - InternalCopy(sourceFileName, destFileName, false); - } - - // Copies an existing file to a new file. If overwrite is - // false, then an IOException is thrown if the destination file - // already exists. If overwrite is true, the file is - // overwritten. - public static void Copy(String sourceFileName, String destFileName, bool overwrite) { - if (sourceFileName == null) - throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName")); - if (destFileName == null) - throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName")); - if (sourceFileName.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceFileName)); - if (destFileName.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName)); - Contract.EndContractBlock(); - - InternalCopy(sourceFileName, destFileName, overwrite); - } - - /// <devdoc> - /// Note: This returns the fully qualified name of the destination file. - /// </devdoc> - internal static String InternalCopy(String sourceFileName, String destFileName, bool overwrite) - { - Contract.Requires(sourceFileName != null); - Contract.Requires(destFileName != null); - Contract.Requires(sourceFileName.Length > 0); - Contract.Requires(destFileName.Length > 0); - - String fullSourceFileName = Path.GetFullPath(sourceFileName); - String fullDestFileName = Path.GetFullPath(destFileName); - - bool r = Win32Native.CopyFile(fullSourceFileName, fullDestFileName, !overwrite); - if (!r) { - // Save Win32 error because subsequent checks will overwrite this HRESULT. - int errorCode = Marshal.GetLastWin32Error(); - String fileName = destFileName; - - if (errorCode != Win32Native.ERROR_FILE_EXISTS) { - if (errorCode == Win32Native.ERROR_ACCESS_DENIED) { - if (Directory.InternalExists(fullDestFileName)) - throw new IOException(Environment.GetResourceString("Arg_FileIsDirectory_Name", destFileName), Win32Native.ERROR_ACCESS_DENIED, fullDestFileName); - } - } - - __Error.WinIOError(errorCode, fileName); - } - - return fullDestFileName; - } - - // Creates a file in a particular path. If the file exists, it is replaced. - // The file is opened with ReadWrite accessand cannot be opened by another - // application until it has been closed. An IOException is thrown if the - // directory specified doesn't exist. - public static FileStream Create(String path) { - return Create(path, FileStream.DefaultBufferSize); - } - - // Creates a file in a particular path. If the file exists, it is replaced. - // The file is opened with ReadWrite access and cannot be opened by another - // application until it has been closed. An IOException is thrown if the - // directory specified doesn't exist. - public static FileStream Create(String path, int bufferSize) { - return new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize); - } - - public static FileStream Create(String path, int bufferSize, FileOptions options) { - return new FileStream(path, FileMode.Create, FileAccess.ReadWrite, - FileShare.None, bufferSize, options); - } - - // Deletes a file. The file specified by the designated path is deleted. - // If the file does not exist, Delete succeeds without throwing - // an exception. - // - // On NT, Delete will fail for a file that is open for normal I/O - // or a file that is memory mapped. - public static void Delete(String path) { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - - InternalDelete(path); - } - - internal static void InternalDelete(String path) - { - String fullPath = Path.GetFullPath(path); - bool r = Win32Native.DeleteFile(fullPath); - if (!r) { - int hr = Marshal.GetLastWin32Error(); - if (hr==Win32Native.ERROR_FILE_NOT_FOUND) - return; - else - __Error.WinIOError(hr, fullPath); - } - } - // Tests if a file exists. The result is true if the file // given by the specified path exists; otherwise, the result is // false. Note that if path describes a directory, @@ -225,193 +82,11 @@ namespace System.IO && ((data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0); } - public static FileStream Open(String path, FileMode mode) { - return Open(path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.None); - } - - public static FileStream Open(String path, FileMode mode, FileAccess access) { - return Open(path,mode, access, FileShare.None); - } - - public static FileStream Open(String path, FileMode mode, FileAccess access, FileShare share) { - return new FileStream(path, mode, access, share); - } - - public static DateTime GetCreationTime(String path) - { - return InternalGetCreationTimeUtc(path).ToLocalTime(); - } - - public static DateTime GetCreationTimeUtc(String path) - { - return InternalGetCreationTimeUtc(path); // this API isn't exposed in Silverlight - } - - private static DateTime InternalGetCreationTimeUtc(String path) - { - String fullPath = Path.GetFullPath(path); - - Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false); - if (dataInitialised != 0) - __Error.WinIOError(dataInitialised, fullPath); - - long dt = ((long)(data.ftCreationTimeHigh) << 32) | ((long)data.ftCreationTimeLow); - return DateTime.FromFileTimeUtc(dt); - } - - public static DateTime GetLastAccessTime(String path) - { - return InternalGetLastAccessTimeUtc(path).ToLocalTime(); - } - - public static DateTime GetLastAccessTimeUtc(String path) - { - return InternalGetLastAccessTimeUtc(path); - } - - private static DateTime InternalGetLastAccessTimeUtc(String path) - { - String fullPath = Path.GetFullPath(path); - - Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false); - if (dataInitialised != 0) - __Error.WinIOError(dataInitialised, fullPath); - - long dt = ((long)(data.ftLastAccessTimeHigh) << 32) | ((long)data.ftLastAccessTimeLow); - return DateTime.FromFileTimeUtc(dt); - } - - public static DateTime GetLastWriteTime(String path) - { - return InternalGetLastWriteTimeUtc(path).ToLocalTime(); - } - - public static DateTime GetLastWriteTimeUtc(String path) - { - return InternalGetLastWriteTimeUtc(path); - } - - private static DateTime InternalGetLastWriteTimeUtc(String path) - { - String fullPath = Path.GetFullPath(path); - - Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false); - if (dataInitialised != 0) - __Error.WinIOError(dataInitialised, fullPath); - - long dt = ((long)data.ftLastWriteTimeHigh << 32) | ((long)data.ftLastWriteTimeLow); - return DateTime.FromFileTimeUtc(dt); - } - - public static FileAttributes GetAttributes(String path) - { - String fullPath = Path.GetFullPath(path); - - Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - int dataInitialised = FillAttributeInfo(fullPath, ref data, false, true); - if (dataInitialised != 0) - __Error.WinIOError(dataInitialised, fullPath); - - return (FileAttributes) data.fileAttributes; - } - - public static void SetAttributes(String path, FileAttributes fileAttributes) - { - String fullPath = Path.GetFullPath(path); - bool r = Win32Native.SetFileAttributes(fullPath, (int) fileAttributes); - if (!r) { - int hr = Marshal.GetLastWin32Error(); - if (hr==ERROR_INVALID_PARAMETER) - throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileAttrs")); - __Error.WinIOError(hr, fullPath); - } - } - - public static FileStream OpenRead(String path) { - return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); - } - - public static FileStream OpenWrite(String path) { - return new FileStream(path, FileMode.OpenOrCreate, - FileAccess.Write, FileShare.None); - } - - public static String ReadAllText(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - return InternalReadAllText(path, Encoding.UTF8); - } - - public static String ReadAllText(String path, Encoding encoding) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (encoding == null) - throw new ArgumentNullException(nameof(encoding)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - return InternalReadAllText(path, encoding); - } - - private static String InternalReadAllText(String path, Encoding encoding) - { - Contract.Requires(path != null); - Contract.Requires(encoding != null); - Contract.Requires(path.Length > 0); - - using (StreamReader sr = new StreamReader(path, encoding, true, StreamReader.DefaultBufferSize)) - return sr.ReadToEnd(); - } - - public static void WriteAllText(String path, String contents) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - InternalWriteAllText(path, contents, StreamWriter.UTF8NoBOM); - } - - public static void WriteAllText(String path, String contents, Encoding encoding) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (encoding == null) - throw new ArgumentNullException(nameof(encoding)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - InternalWriteAllText(path, contents, encoding); - } - - private static void InternalWriteAllText(String path, String contents, Encoding encoding) - { - Contract.Requires(path != null); - Contract.Requires(encoding != null); - Contract.Requires(path.Length > 0); - - using (StreamWriter sw = new StreamWriter(path, false, encoding, StreamWriter.DefaultBufferSize)) - sw.Write(contents); - } - public static byte[] ReadAllBytes(String path) { byte[] bytes; using(FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, - FileStream.DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false)) { + FileStream.DefaultBufferSize, FileOptions.None)) { // Do a blocking read int index = 0; long fileLength = fs.Length; @@ -430,32 +105,7 @@ namespace System.IO return bytes; } - public static void WriteAllBytes(String path, byte[] bytes) - { - if (path == null) - throw new ArgumentNullException(nameof(path), Environment.GetResourceString("ArgumentNull_Path")); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - if (bytes == null) - throw new ArgumentNullException(nameof(bytes)); - Contract.EndContractBlock(); - - InternalWriteAllBytes(path, bytes); - } - - private static void InternalWriteAllBytes(String path, byte[] bytes) - { - Contract.Requires(path != null); - Contract.Requires(path.Length != 0); - Contract.Requires(bytes != null); - - using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, - FileStream.DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false)) - { - fs.Write(bytes, 0, bytes.Length); - } - } - +#if PLATFORM_UNIX public static String[] ReadAllLines(String path) { if (path == null) @@ -467,19 +117,6 @@ namespace System.IO return InternalReadAllLines(path, Encoding.UTF8); } - public static String[] ReadAllLines(String path, Encoding encoding) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (encoding == null) - throw new ArgumentNullException(nameof(encoding)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - return InternalReadAllLines(path, encoding); - } - private static String[] InternalReadAllLines(String path, Encoding encoding) { Contract.Requires(path != null); @@ -495,236 +132,8 @@ namespace System.IO return lines.ToArray(); } - - public static IEnumerable<String> ReadLines(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"), nameof(path)); - Contract.EndContractBlock(); - - return ReadLinesIterator.CreateIterator(path, Encoding.UTF8); - } - - public static IEnumerable<String> ReadLines(String path, Encoding encoding) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (encoding == null) - throw new ArgumentNullException(nameof(encoding)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"), nameof(path)); - Contract.EndContractBlock(); - - return ReadLinesIterator.CreateIterator(path, encoding); - } - - public static void WriteAllLines(String path, String[] contents) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (contents == null) - throw new ArgumentNullException(nameof(contents)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - InternalWriteAllLines(new StreamWriter(path, false, StreamWriter.UTF8NoBOM), contents); - } - - public static void WriteAllLines(String path, String[] contents, Encoding encoding) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (contents == null) - throw new ArgumentNullException(nameof(contents)); - if (encoding == null) - throw new ArgumentNullException(nameof(encoding)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - InternalWriteAllLines(new StreamWriter(path, false, encoding), contents); - } - - public static void WriteAllLines(String path, IEnumerable<String> contents) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (contents == null) - throw new ArgumentNullException(nameof(contents)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - InternalWriteAllLines(new StreamWriter(path, false, StreamWriter.UTF8NoBOM), contents); - } - - public static void WriteAllLines(String path, IEnumerable<String> contents, Encoding encoding) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (contents == null) - throw new ArgumentNullException(nameof(contents)); - if (encoding == null) - throw new ArgumentNullException(nameof(encoding)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - InternalWriteAllLines(new StreamWriter(path, false, encoding), contents); - } - - private static void InternalWriteAllLines(TextWriter writer, IEnumerable<String> contents) - { - Contract.Requires(writer != null); - Contract.Requires(contents != null); - - using (writer) - { - foreach (String line in contents) - { - writer.WriteLine(line); - } - } - } - - public static void AppendAllText(String path, String contents) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - InternalAppendAllText(path, contents, StreamWriter.UTF8NoBOM); - } - - public static void AppendAllText(String path, String contents, Encoding encoding) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (encoding == null) - throw new ArgumentNullException(nameof(encoding)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - InternalAppendAllText(path, contents, encoding); - } - - private static void InternalAppendAllText(String path, String contents, Encoding encoding) - { - Contract.Requires(path != null); - Contract.Requires(encoding != null); - Contract.Requires(path.Length > 0); - - using (StreamWriter sw = new StreamWriter(path, true, encoding)) - sw.Write(contents); - } - - public static void AppendAllLines(String path, IEnumerable<String> contents) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (contents == null) - throw new ArgumentNullException(nameof(contents)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - InternalWriteAllLines(new StreamWriter(path, true, StreamWriter.UTF8NoBOM), contents); - } - - public static void AppendAllLines(String path, IEnumerable<String> contents, Encoding encoding) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (contents == null) - throw new ArgumentNullException(nameof(contents)); - if (encoding == null) - throw new ArgumentNullException(nameof(encoding)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - InternalWriteAllLines(new StreamWriter(path, true, encoding), contents); - } - - // Moves a specified file to a new location and potentially a new file name. - // This method does work across volumes. - public static void Move(String sourceFileName, String destFileName) { - InternalMove(sourceFileName, destFileName); - } - - private static void InternalMove(String sourceFileName, String destFileName) { - if (sourceFileName == null) - throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName")); - if (destFileName == null) - throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName")); - if (sourceFileName.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceFileName)); - if (destFileName.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName)); - Contract.EndContractBlock(); - - String fullSourceFileName = Path.GetFullPath(sourceFileName); - String fullDestFileName = Path.GetFullPath(destFileName); - - if (!InternalExists(fullSourceFileName)) - __Error.WinIOError(Win32Native.ERROR_FILE_NOT_FOUND, fullSourceFileName); - - if (!Win32Native.MoveFile(fullSourceFileName, fullDestFileName)) - { - __Error.WinIOError(); - } - } - - - public static void Replace(String sourceFileName, String destinationFileName, String destinationBackupFileName) - { - if (sourceFileName == null) - throw new ArgumentNullException(nameof(sourceFileName)); - if (destinationFileName == null) - throw new ArgumentNullException(nameof(destinationFileName)); - Contract.EndContractBlock(); - - InternalReplace(sourceFileName, destinationFileName, destinationBackupFileName, false); - } - - public static void Replace(String sourceFileName, String destinationFileName, String destinationBackupFileName, bool ignoreMetadataErrors) - { - if (sourceFileName == null) - throw new ArgumentNullException(nameof(sourceFileName)); - if (destinationFileName == null) - throw new ArgumentNullException(nameof(destinationFileName)); - Contract.EndContractBlock(); - - InternalReplace(sourceFileName, destinationFileName, destinationBackupFileName, ignoreMetadataErrors); - } - - private static void InternalReplace(String sourceFileName, String destinationFileName, String destinationBackupFileName, bool ignoreMetadataErrors) - { - Contract.Requires(sourceFileName != null); - Contract.Requires(destinationFileName != null); - - String fullSrcPath = Path.GetFullPath(sourceFileName); - String fullDestPath = Path.GetFullPath(destinationFileName); - String fullBackupPath = null; - if (destinationBackupFileName != null) - fullBackupPath = Path.GetFullPath(destinationBackupFileName); - - int flags = Win32Native.REPLACEFILE_WRITE_THROUGH; - if (ignoreMetadataErrors) - flags |= Win32Native.REPLACEFILE_IGNORE_MERGE_ERRORS; - - bool r = Win32Native.ReplaceFile(fullDestPath, fullSrcPath, fullBackupPath, flags, IntPtr.Zero, IntPtr.Zero); - if (!r) - __Error.WinIOError(); - } - - +#endif // PLATFORM_UNIX + // Returns 0 on success, otherwise a Win32 error code. Note that // classes should use -1 as the uninitialized state for dataInitialized. internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain, bool returnErrorOnNotFound) diff --git a/src/mscorlib/src/System/IO/FileAccess.cs b/src/mscorlib/src/System/IO/FileAccess.cs index f708a284c1..707b58f78b 100644 --- a/src/mscorlib/src/System/IO/FileAccess.cs +++ b/src/mscorlib/src/System/IO/FileAccess.cs @@ -23,7 +23,6 @@ namespace System.IO { // [Serializable] [Flags] -[System.Runtime.InteropServices.ComVisible(true)] public enum FileAccess { // Specifies read access to the file. Data can be read from the file and diff --git a/src/mscorlib/src/System/IO/FileAttributes.cs b/src/mscorlib/src/System/IO/FileAttributes.cs deleted file mode 100644 index 51ef597f9d..0000000000 --- a/src/mscorlib/src/System/IO/FileAttributes.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/*============================================================ -** -** -** Purpose: File attribute flags corresponding to NT's flags. -** -** -===========================================================*/ -using System; - -namespace System.IO -{ - // File attributes for use with the FileEnumerator class. - // These constants correspond to the constants in WinNT.h. - [Serializable] - [Flags] - [System.Runtime.InteropServices.ComVisible(true)] - public enum FileAttributes - { - // From WinNT.h (FILE_ATTRIBUTE_XXX) - ReadOnly = 0x1, - Hidden = 0x2, - System = 0x4, - Directory = 0x10, - Archive = 0x20, - Device = 0x40, - Normal = 0x80, - Temporary = 0x100, - SparseFile = 0x200, - ReparsePoint = 0x400, - Compressed = 0x800, - Offline = 0x1000, - NotContentIndexed = 0x2000, - Encrypted = 0x4000, - } -} diff --git a/src/mscorlib/src/System/IO/FileInfo.cs b/src/mscorlib/src/System/IO/FileInfo.cs deleted file mode 100644 index 32622c63a1..0000000000 --- a/src/mscorlib/src/System/IO/FileInfo.cs +++ /dev/null @@ -1,270 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Win32Native = Microsoft.Win32.Win32Native; -using System.Runtime.InteropServices; -using System.Text; -using System.Runtime.Serialization; -using System.Globalization; -using System.Runtime.Versioning; -using System.Diagnostics; -using System.Diagnostics.Contracts; - -namespace System.IO -{ - // Class for creating FileStream objects, and some basic file management - // routines such as Delete, etc. - [Serializable] - [ComVisible(true)] - public sealed class FileInfo: FileSystemInfo - { - private String _name; - - // Migrating InheritanceDemands requires this default ctor, so we can annotate it. - private FileInfo(){} - - public FileInfo(String fileName) - { - if (fileName == null) - throw new ArgumentNullException(nameof(fileName)); - Contract.EndContractBlock(); - - Init(fileName); - } - - private void Init(String fileName) - { - OriginalPath = fileName; - _name = Path.GetFileName(fileName); - FullPath = Path.GetFullPath(fileName); - DisplayPath = GetDisplayPath(fileName); - } - - private String GetDisplayPath(String originalPath) - { - return Path.GetFileName(originalPath); - } - - private FileInfo(SerializationInfo info, StreamingContext context) : base(info, context) - { - _name = Path.GetFileName(OriginalPath); - DisplayPath = GetDisplayPath(OriginalPath); - } - - internal FileInfo(String fullPath, bool ignoreThis) - { - Debug.Assert(PathInternal.GetRootLength(fullPath) > 0, "fullPath must be fully qualified!"); - _name = Path.GetFileName(fullPath); - OriginalPath = _name; - FullPath = fullPath; - DisplayPath = _name; - } - - public override String Name { - get { return _name; } - } - - public long Length { - get { - if (_dataInitialised == -1) - Refresh(); - - if (_dataInitialised != 0) // Refresh was unable to initialise the data - __Error.WinIOError(_dataInitialised, DisplayPath); - - if ((_data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0) - __Error.WinIOError(Win32Native.ERROR_FILE_NOT_FOUND, DisplayPath); - - return ((long)_data.fileSizeHigh) << 32 | ((long)_data.fileSizeLow & 0xFFFFFFFFL); - } - } - - /* Returns the name of the directory that the file is in */ - public String DirectoryName - { - get - { - return Path.GetDirectoryName(FullPath); - } - } - - /* Creates an instance of the the parent directory */ - public DirectoryInfo Directory - { - get - { - String dirName = DirectoryName; - if (dirName == null) - return null; - return new DirectoryInfo(dirName); - } - } - - public bool IsReadOnly { - get { - return (Attributes & FileAttributes.ReadOnly) != 0; - } - set { - if (value) - Attributes |= FileAttributes.ReadOnly; - else - Attributes &= ~FileAttributes.ReadOnly; - } - } - - public StreamReader OpenText() - { - return new StreamReader(FullPath, Encoding.UTF8, true, StreamReader.DefaultBufferSize); - } - - public StreamWriter CreateText() - { - return new StreamWriter(FullPath,false); - } - - public StreamWriter AppendText() - { - return new StreamWriter(FullPath,true); - } - - // Copies an existing file to a new file. An exception is raised if the - // destination file already exists. Use the - // Copy(String, String, boolean) method to allow - // overwriting an existing file. - public FileInfo CopyTo(String destFileName) { - if (destFileName == null) - throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName")); - if (destFileName.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName)); - Contract.EndContractBlock(); - - destFileName = File.InternalCopy(FullPath, destFileName, false); - return new FileInfo(destFileName, false); - } - - // Copies an existing file to a new file. If overwrite is - // false, then an IOException is thrown if the destination file - // already exists. If overwrite is true, the file is - // overwritten. - public FileInfo CopyTo(String destFileName, bool overwrite) { - if (destFileName == null) - throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName")); - if (destFileName.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName)); - Contract.EndContractBlock(); - - destFileName = File.InternalCopy(FullPath, destFileName, overwrite); - return new FileInfo(destFileName, false); - } - - public FileStream Create() { - return File.Create(FullPath); - } - - // Deletes a file. The file specified by the designated path is deleted. - // If the file does not exist, Delete succeeds without throwing - // an exception. - // - // On NT, Delete will fail for a file that is open for normal I/O - // or a file that is memory mapped. - public override void Delete() - { - bool r = Win32Native.DeleteFile(FullPath); - if (!r) { - int hr = Marshal.GetLastWin32Error(); - if (hr==Win32Native.ERROR_FILE_NOT_FOUND) - return; - else - __Error.WinIOError(hr, DisplayPath); - } - } - - // Tests if the given file exists. The result is true if the file - // given by the specified path exists; otherwise, the result is - // false. - public override bool Exists { - get { - try { - if (_dataInitialised == -1) - Refresh(); - if (_dataInitialised != 0) { - // Refresh was unable to initialise the data. - // We should normally be throwing an exception here, - // but Exists is supposed to return true or false. - return false; - } - return (_data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0; - } - catch - { - return false; - } - } - } - - // User must explicitly specify opening a new file or appending to one. - public FileStream Open(FileMode mode) { - return Open(mode, FileAccess.ReadWrite, FileShare.None); - } - - public FileStream Open(FileMode mode, FileAccess access) { - return Open(mode, access, FileShare.None); - } - - public FileStream Open(FileMode mode, FileAccess access, FileShare share) { - return new FileStream(FullPath, mode, access, share); - } - - public FileStream OpenRead() - { - return new FileStream(FullPath, FileMode.Open, FileAccess.Read, - FileShare.Read, 4096, false); - } - - public FileStream OpenWrite() { - return new FileStream(FullPath, FileMode.OpenOrCreate, - FileAccess.Write, FileShare.None); - } - - // Moves a given file to a new location and potentially a new file name. - // This method does work across volumes. - public void MoveTo(String destFileName) { - if (destFileName==null) - throw new ArgumentNullException(nameof(destFileName)); - if (destFileName.Length==0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName)); - Contract.EndContractBlock(); - - string fullDestFileName = Path.GetFullPath(destFileName); - - if (!Win32Native.MoveFile(FullPath, fullDestFileName)) - __Error.WinIOError(); - FullPath = fullDestFileName; - OriginalPath = destFileName; - _name = Path.GetFileName(fullDestFileName); - DisplayPath = GetDisplayPath(destFileName); - // Flush any cached information about the file. - _dataInitialised = -1; - } - - [ComVisible(false)] - public FileInfo Replace(String destinationFileName, String destinationBackupFileName) - { - return Replace(destinationFileName, destinationBackupFileName, false); - } - - [ComVisible(false)] - public FileInfo Replace(String destinationFileName, String destinationBackupFileName, bool ignoreMetadataErrors) - { - File.Replace(FullPath, destinationFileName, destinationBackupFileName, ignoreMetadataErrors); - return new FileInfo(destinationFileName); - } - - // Returns the display path - public override String ToString() - { - return DisplayPath; - } - } -} diff --git a/src/mscorlib/src/System/IO/FileLoadException.cs b/src/mscorlib/src/System/IO/FileLoadException.cs index 2b56c00191..980d2514aa 100644 --- a/src/mscorlib/src/System/IO/FileLoadException.cs +++ b/src/mscorlib/src/System/IO/FileLoadException.cs @@ -20,14 +20,12 @@ using System.Runtime.Serialization; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Security; -using System.Security.Permissions; using System.Runtime.Versioning; using SecurityException = System.Security.SecurityException; namespace System.IO { [Serializable] - [System.Runtime.InteropServices.ComVisible(true)] public class FileLoadException : IOException { private String _fileName; // the name of the file we could not load. diff --git a/src/mscorlib/src/System/IO/FileMode.cs b/src/mscorlib/src/System/IO/FileMode.cs index 9b9c2024a7..3972cf0533 100644 --- a/src/mscorlib/src/System/IO/FileMode.cs +++ b/src/mscorlib/src/System/IO/FileMode.cs @@ -27,7 +27,6 @@ namespace System.IO { // exist, use Create. // [Serializable] -[System.Runtime.InteropServices.ComVisible(true)] public enum FileMode { // Creates a new file. An exception is raised if the file already exists. diff --git a/src/mscorlib/src/System/IO/FileNotFoundException.cs b/src/mscorlib/src/System/IO/FileNotFoundException.cs index 8cc75f8232..ad6b5386ba 100644 --- a/src/mscorlib/src/System/IO/FileNotFoundException.cs +++ b/src/mscorlib/src/System/IO/FileNotFoundException.cs @@ -16,14 +16,12 @@ using System; using System.Runtime.Serialization; -using System.Security.Permissions; using SecurityException = System.Security.SecurityException; using System.Globalization; namespace System.IO { // Thrown when trying to access a file that doesn't exist on disk. [Serializable] - [System.Runtime.InteropServices.ComVisible(true)] public class FileNotFoundException : IOException { private String _fileName; // The name of the file that isn't found. diff --git a/src/mscorlib/src/System/IO/FileOptions.cs b/src/mscorlib/src/System/IO/FileOptions.cs index ffd6ddad90..02bc99eea4 100644 --- a/src/mscorlib/src/System/IO/FileOptions.cs +++ b/src/mscorlib/src/System/IO/FileOptions.cs @@ -24,7 +24,6 @@ namespace System.IO { // a number of them made sense in managed code, at least not yet. [Serializable] [Flags] - [ComVisible(true)] public enum FileOptions { // NOTE: any change to FileOptions enum needs to be diff --git a/src/mscorlib/src/System/IO/FileShare.cs b/src/mscorlib/src/System/IO/FileShare.cs index ad76d5da09..8a7d1f05e9 100644 --- a/src/mscorlib/src/System/IO/FileShare.cs +++ b/src/mscorlib/src/System/IO/FileShare.cs @@ -28,7 +28,6 @@ namespace System.IO { // [Serializable] [Flags] -[System.Runtime.InteropServices.ComVisible(true)] public enum FileShare { // No sharing. Any request to open the file (by this process or another diff --git a/src/mscorlib/src/System/IO/FileSystemEnumerable.cs b/src/mscorlib/src/System/IO/FileSystemEnumerable.cs index f861805ccf..0316de0f93 100644 --- a/src/mscorlib/src/System/IO/FileSystemEnumerable.cs +++ b/src/mscorlib/src/System/IO/FileSystemEnumerable.cs @@ -25,7 +25,6 @@ using System.Threading; namespace System.IO { - // Overview: // The key methods instantiate FileSystemEnumerableIterators. These compose the iterator with search result // handlers that instantiate the FileInfo, DirectoryInfo, String, etc. The handlers then perform any @@ -42,37 +41,6 @@ namespace System.IO SearchResultHandler<String> handler = new StringResultHandler(includeFiles, includeDirs); return new FileSystemEnumerableIterator<String>(path, originalUserPath, searchPattern, searchOption, handler, checkHost); } - - internal static IEnumerable<FileInfo> CreateFileInfoIterator(String path, String originalUserPath, String searchPattern, SearchOption searchOption) - { - Contract.Requires(path != null); - Contract.Requires(originalUserPath != null); - Contract.Requires(searchPattern != null); - - SearchResultHandler<FileInfo> handler = new FileInfoResultHandler(); - return new FileSystemEnumerableIterator<FileInfo>(path, originalUserPath, searchPattern, searchOption, handler, true); - } - - internal static IEnumerable<DirectoryInfo> CreateDirectoryInfoIterator(String path, String originalUserPath, String searchPattern, SearchOption searchOption) - { - - Contract.Requires(path != null); - Contract.Requires(originalUserPath != null); - Contract.Requires(searchPattern != null); - - SearchResultHandler<DirectoryInfo> handler = new DirectoryInfoResultHandler(); - return new FileSystemEnumerableIterator<DirectoryInfo>(path, originalUserPath, searchPattern, searchOption, handler, true); - } - - internal static IEnumerable<FileSystemInfo> CreateFileSystemInfoIterator(String path, String originalUserPath, String searchPattern, SearchOption searchOption) - { - Contract.Requires(path != null); - Contract.Requires(originalUserPath != null); - Contract.Requires(searchPattern != null); - - SearchResultHandler<FileSystemInfo> handler = new FileSystemInfoResultHandler(); - return new FileSystemEnumerableIterator<FileSystemInfo>(path, originalUserPath, searchPattern, searchOption, handler, true); - } } // Abstract Iterator, borrowed from Linq. Used in anticipation of need for similar enumerables @@ -166,11 +134,11 @@ namespace System.IO private String searchCriteria; SafeFindHandle _hnd = null; - // empty means we know in advance that we won’t find any search results, which can happen if: - // 1. we don’t have a search pattern - // 2. we’re enumerating only the top directory and found no matches during the first call - // This flag allows us to return early for these cases. We can’t know this in advance for - // SearchOption.AllDirectories because we do a “*” search for subdirs and then use the + // empty means we know in advance that we won't find any search results, which can happen if: + // 1. we don't have a search pattern + // 2. we're enumerating only the top directory and found no matches during the first call + // This flag allows us to return early for these cases. We can't know this in advance for + // SearchOption.AllDirectories because we do a "*" search for subdirs and then use the // searchPattern at each directory level. bool empty; @@ -603,71 +571,6 @@ namespace System.IO } } - internal class FileInfoResultHandler : SearchResultHandler<FileInfo> - { - internal override bool IsResultIncluded(SearchResult result) - { - return FileSystemEnumerableHelpers.IsFile(result.FindData); - } - - internal override FileInfo CreateObject(SearchResult result) - { - String name = result.FullPath; - FileInfo fi = new FileInfo(name, false); - fi.InitializeFrom(result.FindData); - return fi; - } - } - - internal class DirectoryInfoResultHandler : SearchResultHandler<DirectoryInfo> - { - internal override bool IsResultIncluded(SearchResult result) - { - return FileSystemEnumerableHelpers.IsDir(result.FindData); - } - - internal override DirectoryInfo CreateObject(SearchResult result) - { - DirectoryInfo di = new DirectoryInfo(result.FullPath, false); - di.InitializeFrom(result.FindData); - return di; - } - } - - internal class FileSystemInfoResultHandler : SearchResultHandler<FileSystemInfo> - { - - internal override bool IsResultIncluded(SearchResult result) - { - bool includeFile = FileSystemEnumerableHelpers.IsFile(result.FindData); - bool includeDir = FileSystemEnumerableHelpers.IsDir(result.FindData); - Debug.Assert(!(includeFile && includeDir), result.FindData.cFileName + ": current item can't be both file and dir!"); - - return (includeDir || includeFile); - } - - internal override FileSystemInfo CreateObject(SearchResult result) - { - bool isFile = FileSystemEnumerableHelpers.IsFile(result.FindData); - bool isDir = FileSystemEnumerableHelpers.IsDir(result.FindData); - - if (isDir) - { - DirectoryInfo di = new DirectoryInfo(result.FullPath, false); - di.InitializeFrom(result.FindData); - return di; - } - else - { - Contract.Assert(isFile); - FileInfo fi = new FileInfo(result.FullPath, false); - fi.InitializeFrom(result.FindData); - return fi; - } - } - - } - internal sealed class SearchResult { private String fullPath; // fully-qualifed path diff --git a/src/mscorlib/src/System/IO/FileSystemInfo.cs b/src/mscorlib/src/System/IO/FileSystemInfo.cs deleted file mode 100644 index 94cd531b07..0000000000 --- a/src/mscorlib/src/System/IO/FileSystemInfo.cs +++ /dev/null @@ -1,240 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.Win32; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Diagnostics.Contracts; - -namespace System.IO -{ -#if FEATURE_SERIALIZATION - [Serializable] -#endif - [ComVisible(true)] - public abstract class FileSystemInfo : MarshalByRefObject, ISerializable { - - internal Win32Native.WIN32_FILE_ATTRIBUTE_DATA _data; // Cache the file information - internal int _dataInitialised = -1; // We use this field in conjunction with the Refresh methods, if we succeed - // we store a zero, on failure we store the HResult in it so that we can - // give back a generic error back. - - private const int ERROR_INVALID_PARAMETER = 87; - internal const int ERROR_ACCESS_DENIED = 0x5; - - protected String FullPath; // fully qualified path of the directory - protected String OriginalPath; // path passed in by the user - private String _displayPath = ""; // path that can be displayed to the user - - protected FileSystemInfo() - { - } - - protected FileSystemInfo(SerializationInfo info, StreamingContext context) - { - if (info == null) - throw new ArgumentNullException(nameof(info)); - Contract.EndContractBlock(); - - // Must use V1 field names here, since V1 didn't implement - // ISerializable. - FullPath = Path.GetFullPath(info.GetString("FullPath")); - OriginalPath = info.GetString("OriginalPath"); - - // Lazily initialize the file attributes. - _dataInitialised = -1; - } - - internal void InitializeFrom(Win32Native.WIN32_FIND_DATA findData) - { - _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - _data.PopulateFrom(findData); - _dataInitialised = 0; - } - - // Full path of the direcory/file - public virtual String FullName { - get - { - return FullPath; - } - } - - public String Extension - { - get - { - // GetFullPathInternal would have already stripped out the terminating "." if present. - int length = FullPath.Length; - for (int i = length; --i >= 0;) { - char ch = FullPath[i]; - if (ch == '.') - return FullPath.Substring(i, length - i); - if (ch == Path.DirectorySeparatorChar || ch == Path.AltDirectorySeparatorChar || ch == Path.VolumeSeparatorChar) - break; - } - return String.Empty; - } - } - - // For files name of the file is returned, for directories the last directory in hierarchy is returned if possible, - // otherwise the fully qualified name s returned - public abstract String Name { - get; - } - - // Whether a file/directory exists - public abstract bool Exists - { - get; - } - - // Delete a file/directory - public abstract void Delete(); - - public DateTime CreationTime - { - get { - // depends on the security check in get_CreationTimeUtc - return CreationTimeUtc.ToLocalTime(); - } - } - - [ComVisible(false)] - public DateTime CreationTimeUtc { - get { - if (_dataInitialised == -1) { - _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - Refresh(); - } - - if (_dataInitialised != 0) // Refresh was unable to initialise the data - __Error.WinIOError(_dataInitialised, DisplayPath); - - long fileTime = ((long)_data.ftCreationTimeHigh << 32) | _data.ftCreationTimeLow; - return DateTime.FromFileTimeUtc(fileTime); - - } - } - - public DateTime LastAccessTime - { - get { - // depends on the security check in get_LastAccessTimeUtc - return LastAccessTimeUtc.ToLocalTime(); - } - set { - LastAccessTimeUtc = value.ToUniversalTime(); - } - } - - [ComVisible(false)] - public DateTime LastAccessTimeUtc { - get { - if (_dataInitialised == -1) { - _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - Refresh(); - } - - if (_dataInitialised != 0) // Refresh was unable to initialise the data - __Error.WinIOError(_dataInitialised, DisplayPath); - - long fileTime = ((long)_data.ftLastAccessTimeHigh << 32) | _data.ftLastAccessTimeLow; - return DateTime.FromFileTimeUtc(fileTime); - } - - set { - } - } - - public DateTime LastWriteTime - { - get { - // depends on the security check in get_LastWriteTimeUtc - return LastWriteTimeUtc.ToLocalTime(); - } - - set { - LastWriteTimeUtc = value.ToUniversalTime(); - } - } - - [ComVisible(false)] - public DateTime LastWriteTimeUtc { - get { - if (_dataInitialised == -1) { - _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - Refresh(); - } - - if (_dataInitialised != 0) // Refresh was unable to initialise the data - __Error.WinIOError(_dataInitialised, DisplayPath); - - - long fileTime = ((long)_data.ftLastWriteTimeHigh << 32) | _data.ftLastWriteTimeLow; - return DateTime.FromFileTimeUtc(fileTime); - } - - set { - } - } - - public void Refresh() - { - _dataInitialised = File.FillAttributeInfo(FullPath, ref _data, false, false); - } - - public FileAttributes Attributes { - get - { - if (_dataInitialised == -1) { - _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); - Refresh(); // Call refresh to intialise the data - } - - if (_dataInitialised != 0) // Refresh was unable to initialise the data - __Error.WinIOError(_dataInitialised, DisplayPath); - - return (FileAttributes) _data.fileAttributes; - } - - set { - bool r = Win32Native.SetFileAttributes(FullPath, (int) value); - if (!r) { - int hr = Marshal.GetLastWin32Error(); - - if (hr==ERROR_INVALID_PARAMETER) - throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileAttrs")); - - // For whatever reason we are turning ERROR_ACCESS_DENIED into - // ArgumentException here (probably done for some 9x code path). - // We can't change this now but special casing the error message instead. - if (hr == ERROR_ACCESS_DENIED) - throw new ArgumentException(Environment.GetResourceString("UnauthorizedAccess_IODenied_NoPathName")); - __Error.WinIOError(hr, DisplayPath); - } - _dataInitialised = -1; - } - } - - [ComVisible(false)] - public virtual void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("OriginalPath", OriginalPath, typeof(String)); - info.AddValue("FullPath", FullPath, typeof(String)); - } - - internal String DisplayPath - { - get - { - return _displayPath; - } - set - { - _displayPath = value; - } - } - } -} diff --git a/src/mscorlib/src/System/IO/IOException.cs b/src/mscorlib/src/System/IO/IOException.cs index b3db033b0d..ab612811b0 100644 --- a/src/mscorlib/src/System/IO/IOException.cs +++ b/src/mscorlib/src/System/IO/IOException.cs @@ -19,7 +19,6 @@ using System.Runtime.Serialization; namespace System.IO { [Serializable] - [System.Runtime.InteropServices.ComVisible(true)] public class IOException : SystemException { // For debugging purposes, store the complete path in the IOException diff --git a/src/mscorlib/src/System/IO/MemoryStream.cs b/src/mscorlib/src/System/IO/MemoryStream.cs index bdddc83818..05aac909b5 100644 --- a/src/mscorlib/src/System/IO/MemoryStream.cs +++ b/src/mscorlib/src/System/IO/MemoryStream.cs @@ -23,7 +23,6 @@ using System.Diagnostics; using System.Diagnostics.Contracts; using System.Threading; using System.Threading.Tasks; -using System.Security.Permissions; namespace System.IO { // A MemoryStream represents a Stream in memory (ie, it has no backing store). @@ -35,7 +34,6 @@ namespace System.IO { // memory streams are resizable, while ones created with a byte array provide // a stream "view" of the data. [Serializable] - [ComVisible(true)] public class MemoryStream : Stream { private byte[] _buffer; // Either allocated internally or externally. @@ -181,7 +179,6 @@ namespace System.IO { public override void Flush() { } - [ComVisible(false)] public override Task FlushAsync(CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) @@ -357,7 +354,6 @@ namespace System.IO { return n; } - [ComVisible(false)] public override Task<int> ReadAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (buffer==null) @@ -589,7 +585,6 @@ namespace System.IO { } - [ComVisible(false)] public override Task WriteAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (buffer == null) diff --git a/src/mscorlib/src/System/IO/PathTooLongException.cs b/src/mscorlib/src/System/IO/PathTooLongException.cs index b1063232a1..a84fdfbb36 100644 --- a/src/mscorlib/src/System/IO/PathTooLongException.cs +++ b/src/mscorlib/src/System/IO/PathTooLongException.cs @@ -20,7 +20,6 @@ using System.Runtime.Serialization; namespace System.IO { [Serializable] - [System.Runtime.InteropServices.ComVisible(true)] public class PathTooLongException : IOException { public PathTooLongException() diff --git a/src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs b/src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs index 890669fa58..2cbd14f734 100644 --- a/src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs +++ b/src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs @@ -42,8 +42,8 @@ namespace System.IO { _pinningHandle = new GCHandle(array, GCHandleType.Pinned); // Now the byte[] is pinned for the lifetime of this instance. // But I also need to get a pointer to that block of memory... - fixed(byte* ptr = _array) - Initialize(ptr, len, len, FileAccess.Read, true); + fixed(byte* ptr = &_array[0]) + Initialize(ptr, len, len, FileAccess.Read); } ~PinnedBufferMemoryStream() diff --git a/src/mscorlib/src/System/IO/ReadLinesIterator.cs b/src/mscorlib/src/System/IO/ReadLinesIterator.cs deleted file mode 100644 index ce2ad2ad0f..0000000000 --- a/src/mscorlib/src/System/IO/ReadLinesIterator.cs +++ /dev/null @@ -1,102 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -using System; -using System.Diagnostics.Contracts; -using System.Runtime.Versioning; -using System.Text; - -namespace System.IO -{ - // An iterator that returns a single line at-a-time from a given file. - // - // Known issues which cannot be changed to remain compatible with 4.0: - // - // - The underlying StreamReader is allocated upfront for the IEnumerable<T> before - // GetEnumerator has even been called. While this is good in that exceptions such as - // DirectoryNotFoundException and FileNotFoundException are thrown directly by - // File.ReadLines (which the user probably expects), it also means that the reader - // will be leaked if the user never actually foreach's over the enumerable (and hence - // calls Dispose on at least one IEnumerator<T> instance). - // - // - Reading to the end of the IEnumerator<T> disposes it. This means that Dispose - // is called twice in a normal foreach construct. - // - // - IEnumerator<T> instances from the same IEnumerable<T> party on the same underlying - // reader (Dev10 Bugs 904764). - // - internal class ReadLinesIterator : Iterator<string> - { - private readonly string _path; - private readonly Encoding _encoding; - private StreamReader _reader; - - private ReadLinesIterator(string path, Encoding encoding, StreamReader reader) - { - Contract.Requires(path != null); - Contract.Requires(path.Length > 0); - Contract.Requires(encoding != null); - Contract.Requires(reader != null); - - _path = path; - _encoding = encoding; - _reader = reader; - } - - public override bool MoveNext() - { - if (this._reader != null) - { - this.current = _reader.ReadLine(); - if (this.current != null) - return true; - - // To maintain 4.0 behavior we Dispose - // after reading to the end of the reader. - Dispose(); - } - - return false; - } - - protected override Iterator<string> Clone() - { - // NOTE: To maintain the same behavior with the previous yield-based - // iterator in 4.0, we have all the IEnumerator<T> instances share the same - // underlying reader. If we have already been disposed, _reader will be null, - // which will cause CreateIterator to simply new up a new instance to start up - // a new iteration. Dev10 Bugs 904764 has been filed to fix this in next side- - // by-side release. - return CreateIterator(_path, _encoding, _reader); - } - - protected override void Dispose(bool disposing) - { - try - { - if (disposing) - { - if (_reader != null) - { - _reader.Dispose(); - } - } - } - finally - { - _reader = null; - base.Dispose(disposing); - } - } - - internal static ReadLinesIterator CreateIterator(string path, Encoding encoding) - { - return CreateIterator(path, encoding, (StreamReader)null); - } - - private static ReadLinesIterator CreateIterator(string path, Encoding encoding, StreamReader reader) - { - return new ReadLinesIterator(path, encoding, reader ?? new StreamReader(path, encoding)); - } - } -} diff --git a/src/mscorlib/src/System/IO/SearchOption.cs b/src/mscorlib/src/System/IO/SearchOption.cs index aa9b9e37f8..e2f761cd54 100644 --- a/src/mscorlib/src/System/IO/SearchOption.cs +++ b/src/mscorlib/src/System/IO/SearchOption.cs @@ -20,7 +20,6 @@ using System; namespace System.IO { [Serializable] -[System.Runtime.InteropServices.ComVisible(true)] public enum SearchOption { // Include only the current directory in the search operation diff --git a/src/mscorlib/src/System/IO/SeekOrigin.cs b/src/mscorlib/src/System/IO/SeekOrigin.cs index a0a013e7aa..bff49e610f 100644 --- a/src/mscorlib/src/System/IO/SeekOrigin.cs +++ b/src/mscorlib/src/System/IO/SeekOrigin.cs @@ -21,7 +21,6 @@ namespace System.IO { // Provides seek reference points. To seek to the end of a stream, // call stream.Seek(0, SeekOrigin.End). [Serializable] - [System.Runtime.InteropServices.ComVisible(true)] public enum SeekOrigin { // These constants match Win32's FILE_BEGIN, FILE_CURRENT, and FILE_END diff --git a/src/mscorlib/src/System/IO/Stream.cs b/src/mscorlib/src/System/IO/Stream.cs index 3cdfad613e..790f0a09ab 100644 --- a/src/mscorlib/src/System/IO/Stream.cs +++ b/src/mscorlib/src/System/IO/Stream.cs @@ -23,14 +23,12 @@ using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Security; -using System.Security.Permissions; using System.Diagnostics; using System.Diagnostics.Contracts; using System.Reflection; namespace System.IO { [Serializable] - [ComVisible(true)] public abstract class Stream : MarshalByRefObject, IDisposable { public static readonly Stream Null = new NullStream(); @@ -65,7 +63,6 @@ namespace System.IO { get; } - [ComVisible(false)] public virtual bool CanTimeout { [Pure] get { @@ -87,7 +84,6 @@ namespace System.IO { set; } - [ComVisible(false)] public virtual int ReadTimeout { get { Contract.Ensures(Contract.Result<int>() >= 0); @@ -98,7 +94,6 @@ namespace System.IO { } } - [ComVisible(false)] public virtual int WriteTimeout { get { Contract.Ensures(Contract.Result<int>() >= 0); @@ -109,7 +104,6 @@ namespace System.IO { } } - [ComVisible(false)] public Task CopyToAsync(Stream destination) { int bufferSize = _DefaultCopyBufferSize; @@ -146,13 +140,11 @@ namespace System.IO { return CopyToAsync(destination, bufferSize); } - [ComVisible(false)] public Task CopyToAsync(Stream destination, Int32 bufferSize) { return CopyToAsync(destination, bufferSize, CancellationToken.None); } - [ComVisible(false)] public virtual Task CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken) { StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize); @@ -278,13 +270,11 @@ namespace System.IO { public abstract void Flush(); - [ComVisible(false)] public Task FlushAsync() { return FlushAsync(CancellationToken.None); } - [ComVisible(false)] public virtual Task FlushAsync(CancellationToken cancellationToken) { return Task.Factory.StartNew(state => ((Stream)state).Flush(), this, @@ -398,13 +388,11 @@ namespace System.IO { } } - [ComVisible(false)] public Task<int> ReadAsync(Byte[] buffer, int offset, int count) { return ReadAsync(buffer, offset, count, CancellationToken.None); } - [ComVisible(false)] public virtual Task<int> ReadAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken) { // If cancellation was requested, bail early with an already completed task. @@ -617,7 +605,6 @@ namespace System.IO { _buffer = null; } - [MethodImpl(MethodImplOptions.NoInlining)] public ReadWriteTask( bool isRead, bool apm, @@ -630,8 +617,6 @@ namespace System.IO { Contract.Requires(buffer != null); Contract.EndContractBlock(); - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - // Store the arguments _isRead = isRead; _apm = apm; @@ -648,8 +633,7 @@ namespace System.IO { if (callback != null) { _callback = callback; - _context = ExecutionContext.Capture(ref stackMark, - ExecutionContext.CaptureOptions.OptimizeDefaultCase | ExecutionContext.CaptureOptions.IgnoreSyncCtx); + _context = ExecutionContext.Capture(); base.AddCompletionAction(this); } } @@ -683,14 +667,13 @@ namespace System.IO { var invokeAsyncCallback = s_invokeAsyncCallback; if (invokeAsyncCallback == null) s_invokeAsyncCallback = invokeAsyncCallback = InvokeAsyncCallback; // benign race condition - using(context) ExecutionContext.Run(context, invokeAsyncCallback, this, true); + ExecutionContext.Run(context, invokeAsyncCallback, this); } } bool ITaskCompletionAction.InvokeMayRunArbitraryCode { get { return true; } } } - [ComVisible(false)] public Task WriteAsync(Byte[] buffer, int offset, int count) { return WriteAsync(buffer, offset, count, CancellationToken.None); @@ -698,7 +681,6 @@ namespace System.IO { - [ComVisible(false)] public virtual Task WriteAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken) { // If cancellation was requested, bail early with an already completed task. @@ -906,7 +888,6 @@ namespace System.IO { { } - [ComVisible(false)] public override Task FlushAsync(CancellationToken cancellationToken) { return cancellationToken.IsCancellationRequested ? @@ -951,7 +932,6 @@ namespace System.IO { return 0; } - [ComVisible(false)] public override Task<int> ReadAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken) { var nullReadTask = s_nullReadTask; @@ -970,7 +950,6 @@ namespace System.IO { { } - [ComVisible(false)] public override Task WriteAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken) { return cancellationToken.IsCancellationRequested ? @@ -1106,7 +1085,6 @@ namespace System.IO { get { return _stream.CanSeek; } } - [ComVisible(false)] public override bool CanTimeout { [Pure] get { @@ -1135,7 +1113,6 @@ namespace System.IO { } } - [ComVisible(false)] public override int ReadTimeout { get { return _stream.ReadTimeout; @@ -1145,7 +1122,6 @@ namespace System.IO { } } - [ComVisible(false)] public override int WriteTimeout { get { return _stream.WriteTimeout; diff --git a/src/mscorlib/src/System/IO/StreamReader.cs b/src/mscorlib/src/System/IO/StreamReader.cs index 708db088e8..6d50347b1a 100644 --- a/src/mscorlib/src/System/IO/StreamReader.cs +++ b/src/mscorlib/src/System/IO/StreamReader.cs @@ -8,7 +8,6 @@ using System.Runtime.Versioning; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; -using System.Security.Permissions; using System.Threading.Tasks; namespace System.IO @@ -18,8 +17,7 @@ namespace System.IO // whereas the Stream class is designed for byte input and output. // [Serializable] - [System.Runtime.InteropServices.ComVisible(true)] - public class StreamReader : TextReader + internal class StreamReader : TextReader { // StreamReader.Null is threadsafe. public new static readonly StreamReader Null = new NullStreamReader(); @@ -188,7 +186,7 @@ namespace System.IO throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); Contract.EndContractBlock(); - Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.SequentialScan, Path.GetFileName(path), false, false); + Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.SequentialScan); Init(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize, false); } @@ -757,7 +755,6 @@ namespace System.IO } #region Task based Async APIs - [ComVisible(false)] public override Task<String> ReadLineAsync() { // If we have been inherited into a subclass, the following implementation could be incorrect @@ -837,7 +834,6 @@ namespace System.IO return GetStringAndReleaseSharedStringBuilder(sb); } - [ComVisible(false)] public override Task<String> ReadToEndAsync() { // If we have been inherited into a subclass, the following implementation could be incorrect @@ -873,7 +869,6 @@ namespace System.IO return GetStringAndReleaseSharedStringBuilder(sb); } - [ComVisible(false)] public override Task<int> ReadAsync(char[] buffer, int index, int count) { if (buffer==null) @@ -1060,7 +1055,6 @@ namespace System.IO return charsRead; } - [ComVisible(false)] public override Task<int> ReadBlockAsync(char[] buffer, int index, int count) { if (buffer==null) diff --git a/src/mscorlib/src/System/IO/StreamWriter.cs b/src/mscorlib/src/System/IO/StreamWriter.cs deleted file mode 100644 index 22eba82605..0000000000 --- a/src/mscorlib/src/System/IO/StreamWriter.cs +++ /dev/null @@ -1,765 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text; -using System.Runtime.CompilerServices; -using System.Security.Permissions; -using System.Runtime.Serialization; -using System.Diagnostics; -using System.Diagnostics.Contracts; -using System.Runtime.InteropServices; -using System.Threading.Tasks; - -namespace System.IO -{ - // This class implements a TextWriter for writing characters to a Stream. - // This is designed for character output in a particular Encoding, - // whereas the Stream class is designed for byte input and output. - // - [Serializable] - [ComVisible(true)] - public class StreamWriter : TextWriter - { - // For UTF-8, the values of 1K for the default buffer size and 4K for the - // file stream buffer size are reasonable & give very reasonable - // performance for in terms of construction time for the StreamWriter and - // write perf. Note that for UTF-8, we end up allocating a 4K byte buffer, - // which means we take advantage of adaptive buffering code. - // The performance using UnicodeEncoding is acceptable. - internal const int DefaultBufferSize = 1024; // char[] - private const int DefaultFileStreamBufferSize = 4096; - private const int MinBufferSize = 128; - - // Bit bucket - Null has no backing store. Non closable. - public new static readonly StreamWriter Null = new StreamWriter(Stream.Null, UTF8NoBOM, MinBufferSize, true); - - private Stream stream; - private Encoding encoding; - private Encoder encoder; - private byte[] byteBuffer; - private char[] charBuffer; - private int charPos; - private int charLen; - private bool autoFlush; - private bool haveWrittenPreamble; - private bool closable; - - // We don't guarantee thread safety on StreamWriter, but we should at - // least prevent users from trying to write anything while an Async - // write from the same thread is in progress. - [NonSerialized] - private volatile Task _asyncWriteTask; - - private void CheckAsyncTaskInProgress() - { - // We are not locking the access to _asyncWriteTask because this is not meant to guarantee thread safety. - // We are simply trying to deter calling any Write APIs while an async Write from the same thread is in progress. - - Task t = _asyncWriteTask; - - if (t != null && !t.IsCompleted) - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncIOInProgress")); - } - - // The high level goal is to be tolerant of encoding errors when we read and very strict - // when we write. Hence, default StreamWriter encoding will throw on encoding error. - // Note: when StreamWriter throws on invalid encoding chars (for ex, high surrogate character - // D800-DBFF without a following low surrogate character DC00-DFFF), it will cause the - // internal StreamWriter's state to be irrecoverable as it would have buffered the - // illegal chars and any subsequent call to Flush() would hit the encoding error again. - // Even Close() will hit the exception as it would try to flush the unwritten data. - // Maybe we can add a DiscardBufferedData() method to get out of such situation (like - // StreamReader though for different reason). Either way, the buffered data will be lost! - internal static Encoding UTF8NoBOM { - [FriendAccessAllowed] - get { return EncodingCache.UTF8NoBOM; } - } - - - internal StreamWriter(): base(null) { // Ask for CurrentCulture all the time - } - - public StreamWriter(Stream stream) - : this(stream, UTF8NoBOM, DefaultBufferSize, false) { - } - - public StreamWriter(Stream stream, Encoding encoding) - : this(stream, encoding, DefaultBufferSize, false) { - } - - // Creates a new StreamWriter for the given stream. The - // character encoding is set by encoding and the buffer size, - // in number of 16-bit characters, is set by bufferSize. - // - public StreamWriter(Stream stream, Encoding encoding, int bufferSize) - : this(stream, encoding, bufferSize, false) { - } - - public StreamWriter(Stream stream, Encoding encoding, int bufferSize, bool leaveOpen) - : base(null) // Ask for CurrentCulture all the time - { - if (stream == null || encoding == null) - throw new ArgumentNullException((stream == null ? nameof(stream) : nameof(encoding))); - if (!stream.CanWrite) - throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotWritable")); - if (bufferSize <= 0) throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); - Contract.EndContractBlock(); - - Init(stream, encoding, bufferSize, leaveOpen); - } - - public StreamWriter(String path) - : this(path, false, UTF8NoBOM, DefaultBufferSize) { - } - - public StreamWriter(String path, bool append) - : this(path, append, UTF8NoBOM, DefaultBufferSize) { - } - - public StreamWriter(String path, bool append, Encoding encoding) - : this(path, append, encoding, DefaultBufferSize) { - } - - public StreamWriter(String path, bool append, Encoding encoding, int bufferSize) - : base(null) - { - // Ask for CurrentCulture all the time - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (encoding == null) - throw new ArgumentNullException(nameof(encoding)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - if (bufferSize <= 0) throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); - Contract.EndContractBlock(); - - Stream stream = CreateFile(path, append); - Init(stream, encoding, bufferSize, false); - } - - private void Init(Stream streamArg, Encoding encodingArg, int bufferSize, bool shouldLeaveOpen) - { - this.stream = streamArg; - this.encoding = encodingArg; - this.encoder = encoding.GetEncoder(); - if (bufferSize < MinBufferSize) bufferSize = MinBufferSize; - charBuffer = new char[bufferSize]; - byteBuffer = new byte[encoding.GetMaxByteCount(bufferSize)]; - charLen = bufferSize; - // If we're appending to a Stream that already has data, don't write - // the preamble. - if (stream.CanSeek && stream.Position > 0) - haveWrittenPreamble = true; - closable = !shouldLeaveOpen; - } - - private static Stream CreateFile(String path, bool append) { - FileMode mode = append? FileMode.Append: FileMode.Create; - FileStream f = new FileStream(path, mode, FileAccess.Write, FileShare.Read, - DefaultFileStreamBufferSize, FileOptions.SequentialScan, Path.GetFileName(path), false, false); - return f; - } - - public override void Close() { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected override void Dispose(bool disposing) { - try { - // We need to flush any buffered data if we are being closed/disposed. - // Also, we never close the handles for stdout & friends. So we can safely - // write any buffered data to those streams even during finalization, which - // is generally the right thing to do. - if (stream != null) { - // Note: flush on the underlying stream can throw (ex., low disk space) - if (disposing) - { - CheckAsyncTaskInProgress(); - - Flush(true, true); - } - } - } - finally { - // Dispose of our resources if this StreamWriter is closable. - // Note: Console.Out and other such non closable streamwriters should be left alone - if (!LeaveOpen && stream != null) { - try { - // Attempt to close the stream even if there was an IO error from Flushing. - // Note that Stream.Close() can potentially throw here (may or may not be - // due to the same Flush error). In this case, we still need to ensure - // cleaning up internal resources, hence the finally block. - if (disposing) - stream.Close(); - } - finally { - stream = null; - byteBuffer = null; - charBuffer = null; - encoding = null; - encoder = null; - charLen = 0; - base.Dispose(disposing); - } - } - } - } - - public override void Flush() - { - CheckAsyncTaskInProgress(); - - Flush(true, true); - } - - private void Flush(bool flushStream, bool flushEncoder) - { - // flushEncoder should be true at the end of the file and if - // the user explicitly calls Flush (though not if AutoFlush is true). - // This is required to flush any dangling characters from our UTF-7 - // and UTF-8 encoders. - if (stream == null) - __Error.WriterClosed(); - - // Perf boost for Flush on non-dirty writers. - if (charPos==0 && (!flushStream && !flushEncoder)) - return; - - if (!haveWrittenPreamble) { - haveWrittenPreamble = true; - byte[] preamble = encoding.GetPreamble(); - if (preamble.Length > 0) - stream.Write(preamble, 0, preamble.Length); - } - - int count = encoder.GetBytes(charBuffer, 0, charPos, byteBuffer, 0, flushEncoder); - charPos = 0; - if (count > 0) - stream.Write(byteBuffer, 0, count); - // By definition, calling Flush should flush the stream, but this is - // only necessary if we passed in true for flushStream. The Web - // Services guys have some perf tests where flushing needlessly hurts. - if (flushStream) - stream.Flush(); - } - - public virtual bool AutoFlush { - get { return autoFlush; } - - set - { - CheckAsyncTaskInProgress(); - - autoFlush = value; - if (value) Flush(true, false); - } - } - - public virtual Stream BaseStream { - get { return stream; } - } - - internal bool LeaveOpen { - get { return !closable; } - } - - internal bool HaveWrittenPreamble { - set { haveWrittenPreamble= value; } - } - - public override Encoding Encoding { - get { return encoding; } - } - - public override void Write(char value) - { - CheckAsyncTaskInProgress(); - - if (charPos == charLen) Flush(false, false); - charBuffer[charPos] = value; - charPos++; - if (autoFlush) Flush(true, false); - } - - public override void Write(char[] buffer) - { - // This may be faster than the one with the index & count since it - // has to do less argument checking. - if (buffer==null) - return; - - CheckAsyncTaskInProgress(); - - int index = 0; - int count = buffer.Length; - while (count > 0) { - if (charPos == charLen) Flush(false, false); - int n = charLen - charPos; - if (n > count) n = count; - Debug.Assert(n > 0, "StreamWriter::Write(char[]) isn't making progress! This is most likely a race condition in user code."); - Buffer.InternalBlockCopy(buffer, index * sizeof(char), charBuffer, charPos * sizeof(char), n * sizeof(char)); - charPos += n; - index += n; - count -= n; - } - if (autoFlush) Flush(true, false); - } - - public override void Write(char[] buffer, int index, int count) { - if (buffer==null) - throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer")); - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - if (buffer.Length - index < count) - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); - Contract.EndContractBlock(); - - CheckAsyncTaskInProgress(); - - while (count > 0) { - if (charPos == charLen) Flush(false, false); - int n = charLen - charPos; - if (n > count) n = count; - Debug.Assert(n > 0, "StreamWriter::Write(char[], int, int) isn't making progress! This is most likely a race condition in user code."); - Buffer.InternalBlockCopy(buffer, index * sizeof(char), charBuffer, charPos * sizeof(char), n * sizeof(char)); - charPos += n; - index += n; - count -= n; - } - if (autoFlush) Flush(true, false); - } - - public override void Write(String value) - { - if (value != null) - { - - CheckAsyncTaskInProgress(); - - int count = value.Length; - int index = 0; - while (count > 0) { - if (charPos == charLen) Flush(false, false); - int n = charLen - charPos; - if (n > count) n = count; - Debug.Assert(n > 0, "StreamWriter::Write(String) isn't making progress! This is most likely a race condition in user code."); - value.CopyTo(index, charBuffer, charPos, n); - charPos += n; - index += n; - count -= n; - } - if (autoFlush) Flush(true, false); - } - } - - #region Task based Async APIs - [ComVisible(false)] - public override Task WriteAsync(char value) - { - // If we have been inherited into a subclass, the following implementation could be incorrect - // since it does not call through to Write() which a subclass might have overriden. - // To be safe we will only use this implementation in cases where we know it is safe to do so, - // and delegate to our base class (which will call into Write) when we are not sure. - if (this.GetType() != typeof(StreamWriter)) - return base.WriteAsync(value); - - if (stream == null) - __Error.WriterClosed(); - - CheckAsyncTaskInProgress(); - - Task task = WriteAsyncInternal(this, value, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: false); - _asyncWriteTask = task; - - return task; - } - - // We pass in private instance fields of this MarshalByRefObject-derived type as local params - // to ensure performant access inside the state machine that corresponds this async method. - // Fields that are written to must be assigned at the end of the method *and* before instance invocations. - private static async Task WriteAsyncInternal(StreamWriter _this, Char value, - Char[] charBuffer, Int32 charPos, Int32 charLen, Char[] coreNewLine, - bool autoFlush, bool appendNewLine) - { - if (charPos == charLen) { - await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false); - Debug.Assert(_this.charPos == 0); - charPos = 0; - } - - charBuffer[charPos] = value; - charPos++; - - if (appendNewLine) - { - for (Int32 i = 0; i < coreNewLine.Length; i++) // Expect 2 iterations, no point calling BlockCopy - { - if (charPos == charLen) { - await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false); - Debug.Assert(_this.charPos == 0); - charPos = 0; - } - - charBuffer[charPos] = coreNewLine[i]; - charPos++; - } - } - - if (autoFlush) { - await _this.FlushAsyncInternal(true, false, charBuffer, charPos).ConfigureAwait(false); - Debug.Assert(_this.charPos == 0); - charPos = 0; - } - - _this.CharPos_Prop = charPos; - } - - [ComVisible(false)] - public override Task WriteAsync(String value) - { - // If we have been inherited into a subclass, the following implementation could be incorrect - // since it does not call through to Write() which a subclass might have overriden. - // To be safe we will only use this implementation in cases where we know it is safe to do so, - // and delegate to our base class (which will call into Write) when we are not sure. - if (this.GetType() != typeof(StreamWriter)) - return base.WriteAsync(value); - - if (value != null) - { - if (stream == null) - __Error.WriterClosed(); - - CheckAsyncTaskInProgress(); - - Task task = WriteAsyncInternal(this, value, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: false); - _asyncWriteTask = task; - - return task; - } - else - { - return Task.CompletedTask; - } - } - - // We pass in private instance fields of this MarshalByRefObject-derived type as local params - // to ensure performant access inside the state machine that corresponds this async method. - // Fields that are written to must be assigned at the end of the method *and* before instance invocations. - private static async Task WriteAsyncInternal(StreamWriter _this, String value, - Char[] charBuffer, Int32 charPos, Int32 charLen, Char[] coreNewLine, - bool autoFlush, bool appendNewLine) - { - Contract.Requires(value != null); - - int count = value.Length; - int index = 0; - - while (count > 0) - { - if (charPos == charLen) { - await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false); - Debug.Assert(_this.charPos == 0); - charPos = 0; - } - - int n = charLen - charPos; - if (n > count) - n = count; - - Debug.Assert(n > 0, "StreamWriter::Write(String) isn't making progress! This is most likely a race condition in user code."); - - value.CopyTo(index, charBuffer, charPos, n); - - charPos += n; - index += n; - count -= n; - } - - if (appendNewLine) - { - for (Int32 i = 0; i < coreNewLine.Length; i++) // Expect 2 iterations, no point calling BlockCopy - { - if (charPos == charLen) { - await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false); - Debug.Assert(_this.charPos == 0); - charPos = 0; - } - - charBuffer[charPos] = coreNewLine[i]; - charPos++; - } - } - - if (autoFlush) { - await _this.FlushAsyncInternal(true, false, charBuffer, charPos).ConfigureAwait(false); - Debug.Assert(_this.charPos == 0); - charPos = 0; - } - - _this.CharPos_Prop = charPos; - } - - [ComVisible(false)] - public override Task WriteAsync(char[] buffer, int index, int count) - { - if (buffer==null) - throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer")); - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - if (buffer.Length - index < count) - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); - Contract.EndContractBlock(); - - // If we have been inherited into a subclass, the following implementation could be incorrect - // since it does not call through to Write() which a subclass might have overriden. - // To be safe we will only use this implementation in cases where we know it is safe to do so, - // and delegate to our base class (which will call into Write) when we are not sure. - if (this.GetType() != typeof(StreamWriter)) - return base.WriteAsync(buffer, index, count); - - if (stream == null) - __Error.WriterClosed(); - - CheckAsyncTaskInProgress(); - - Task task = WriteAsyncInternal(this, buffer, index, count, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: false); - _asyncWriteTask = task; - - return task; - } - - // We pass in private instance fields of this MarshalByRefObject-derived type as local params - // to ensure performant access inside the state machine that corresponds this async method. - // Fields that are written to must be assigned at the end of the method *and* before instance invocations. - private static async Task WriteAsyncInternal(StreamWriter _this, Char[] buffer, Int32 index, Int32 count, - Char[] charBuffer, Int32 charPos, Int32 charLen, Char[] coreNewLine, - bool autoFlush, bool appendNewLine) - { - Contract.Requires(count == 0 || (count > 0 && buffer != null)); - Contract.Requires(index >= 0); - Contract.Requires(count >= 0); - Contract.Requires(buffer == null || (buffer != null && buffer.Length - index >= count)); - - while (count > 0) - { - if (charPos == charLen) { - await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false); - Debug.Assert(_this.charPos == 0); - charPos = 0; - } - - int n = charLen - charPos; - if (n > count) n = count; - - Debug.Assert(n > 0, "StreamWriter::Write(char[], int, int) isn't making progress! This is most likely a race condition in user code."); - - Buffer.InternalBlockCopy(buffer, index * sizeof(char), charBuffer, charPos * sizeof(char), n * sizeof(char)); - - charPos += n; - index += n; - count -= n; - } - - if (appendNewLine) - { - for (Int32 i = 0; i < coreNewLine.Length; i++) // Expect 2 iterations, no point calling BlockCopy - { - if (charPos == charLen) { - await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false); - Debug.Assert(_this.charPos == 0); - charPos = 0; - } - - charBuffer[charPos] = coreNewLine[i]; - charPos++; - } - } - - if (autoFlush) { - await _this.FlushAsyncInternal(true, false, charBuffer, charPos).ConfigureAwait(false); - Debug.Assert(_this.charPos == 0); - charPos = 0; - } - - _this.CharPos_Prop = charPos; - } - - [ComVisible(false)] - public override Task WriteLineAsync() - { - // If we have been inherited into a subclass, the following implementation could be incorrect - // since it does not call through to Write() which a subclass might have overriden. - // To be safe we will only use this implementation in cases where we know it is safe to do so, - // and delegate to our base class (which will call into Write) when we are not sure. - if (this.GetType() != typeof(StreamWriter)) - return base.WriteLineAsync(); - - if (stream == null) - __Error.WriterClosed(); - - CheckAsyncTaskInProgress(); - - Task task = WriteAsyncInternal(this, null, 0, 0, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: true); - _asyncWriteTask = task; - - return task; - } - - - [ComVisible(false)] - public override Task WriteLineAsync(char value) - { - // If we have been inherited into a subclass, the following implementation could be incorrect - // since it does not call through to Write() which a subclass might have overriden. - // To be safe we will only use this implementation in cases where we know it is safe to do so, - // and delegate to our base class (which will call into Write) when we are not sure. - if (this.GetType() != typeof(StreamWriter)) - return base.WriteLineAsync(value); - - if (stream == null) - __Error.WriterClosed(); - - CheckAsyncTaskInProgress(); - - Task task = WriteAsyncInternal(this, value, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: true); - _asyncWriteTask = task; - - return task; - } - - - [ComVisible(false)] - public override Task WriteLineAsync(String value) - { - // If we have been inherited into a subclass, the following implementation could be incorrect - // since it does not call through to Write() which a subclass might have overriden. - // To be safe we will only use this implementation in cases where we know it is safe to do so, - // and delegate to our base class (which will call into Write) when we are not sure. - if (this.GetType() != typeof(StreamWriter)) - return base.WriteLineAsync(value); - - if (stream == null) - __Error.WriterClosed(); - - CheckAsyncTaskInProgress(); - - Task task = WriteAsyncInternal(this, value, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: true); - _asyncWriteTask = task; - - return task; - } - - - [ComVisible(false)] - public override Task WriteLineAsync(char[] buffer, int index, int count) - { - if (buffer==null) - throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer")); - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - if (buffer.Length - index < count) - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); - Contract.EndContractBlock(); - - // If we have been inherited into a subclass, the following implementation could be incorrect - // since it does not call through to Write() which a subclass might have overriden. - // To be safe we will only use this implementation in cases where we know it is safe to do so, - // and delegate to our base class (which will call into Write) when we are not sure. - if (this.GetType() != typeof(StreamWriter)) - return base.WriteLineAsync(buffer, index, count); - - if (stream == null) - __Error.WriterClosed(); - - CheckAsyncTaskInProgress(); - - Task task = WriteAsyncInternal(this, buffer, index, count, charBuffer, charPos, charLen, CoreNewLine, autoFlush, appendNewLine: true); - _asyncWriteTask = task; - - return task; - } - - - [ComVisible(false)] - public override Task FlushAsync() - { - // If we have been inherited into a subclass, the following implementation could be incorrect - // since it does not call through to Flush() which a subclass might have overriden. To be safe - // we will only use this implementation in cases where we know it is safe to do so, - // and delegate to our base class (which will call into Flush) when we are not sure. - if (this.GetType() != typeof(StreamWriter)) - return base.FlushAsync(); - - // flushEncoder should be true at the end of the file and if - // the user explicitly calls Flush (though not if AutoFlush is true). - // This is required to flush any dangling characters from our UTF-7 - // and UTF-8 encoders. - if (stream == null) - __Error.WriterClosed(); - - CheckAsyncTaskInProgress(); - - Task task = FlushAsyncInternal(true, true, charBuffer, charPos); - _asyncWriteTask = task; - - return task; - } - - private Int32 CharPos_Prop { - set { this.charPos = value; } - } - - private bool HaveWrittenPreamble_Prop { - set { this.haveWrittenPreamble = value; } - } - - private Task FlushAsyncInternal(bool flushStream, bool flushEncoder, - Char[] sCharBuffer, Int32 sCharPos) { - - // Perf boost for Flush on non-dirty writers. - if (sCharPos == 0 && !flushStream && !flushEncoder) - return Task.CompletedTask; - - Task flushTask = FlushAsyncInternal(this, flushStream, flushEncoder, sCharBuffer, sCharPos, this.haveWrittenPreamble, - this.encoding, this.encoder, this.byteBuffer, this.stream); - - this.charPos = 0; - return flushTask; - } - - - // We pass in private instance fields of this MarshalByRefObject-derived type as local params - // to ensure performant access inside the state machine that corresponds this async method. - private static async Task FlushAsyncInternal(StreamWriter _this, bool flushStream, bool flushEncoder, - Char[] charBuffer, Int32 charPos, bool haveWrittenPreamble, - Encoding encoding, Encoder encoder, Byte[] byteBuffer, Stream stream) - { - if (!haveWrittenPreamble) - { - _this.HaveWrittenPreamble_Prop = true; - byte[] preamble = encoding.GetPreamble(); - if (preamble.Length > 0) - await stream.WriteAsync(preamble, 0, preamble.Length).ConfigureAwait(false); - } - - int count = encoder.GetBytes(charBuffer, 0, charPos, byteBuffer, 0, flushEncoder); - if (count > 0) - await stream.WriteAsync(byteBuffer, 0, count).ConfigureAwait(false); - - // By definition, calling Flush should flush the stream, but this is - // only necessary if we passed in true for flushStream. The Web - // Services guys have some perf tests where flushing needlessly hurts. - if (flushStream) - await stream.FlushAsync().ConfigureAwait(false); - } - #endregion - } // class StreamWriter -} // namespace diff --git a/src/mscorlib/src/System/IO/TextReader.cs b/src/mscorlib/src/System/IO/TextReader.cs index 6cbadfbce5..15ba8fba7d 100644 --- a/src/mscorlib/src/System/IO/TextReader.cs +++ b/src/mscorlib/src/System/IO/TextReader.cs @@ -17,7 +17,6 @@ using System.Text; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; -using System.Security.Permissions; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Threading; @@ -32,8 +31,7 @@ namespace System.IO { // This class is intended for character input, not bytes. // There are methods on the Stream class for reading bytes. [Serializable] - [ComVisible(true)] - public abstract class TextReader : MarshalByRefObject, IDisposable { + internal abstract class TextReader : MarshalByRefObject, IDisposable { public static readonly TextReader Null = new NullTextReader(); @@ -170,7 +168,6 @@ namespace System.IO { } #region Task based Async APIs - [ComVisible(false)] public virtual Task<String> ReadLineAsync() { return Task<String>.Factory.StartNew(state => @@ -180,7 +177,6 @@ namespace System.IO { this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } - [ComVisible(false)] public async virtual Task<String> ReadToEndAsync() { char[] chars = new char[4096]; @@ -193,7 +189,6 @@ namespace System.IO { return sb.ToString(); } - [ComVisible(false)] public virtual Task<int> ReadAsync(char[] buffer, int index, int count) { if (buffer==null) @@ -223,7 +218,6 @@ namespace System.IO { tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } - [ComVisible(false)] public virtual Task<int> ReadBlockAsync(char[] buffer, int index, int count) { if (buffer==null) @@ -352,21 +346,18 @@ namespace System.IO { // On SyncTextReader all APIs should run synchronously, even the async ones. // - [ComVisible(false)] [MethodImplAttribute(MethodImplOptions.Synchronized)] public override Task<String> ReadLineAsync() { return Task.FromResult(ReadLine()); } - [ComVisible(false)] [MethodImplAttribute(MethodImplOptions.Synchronized)] public override Task<String> ReadToEndAsync() { return Task.FromResult(ReadToEnd()); } - [ComVisible(false)] [MethodImplAttribute(MethodImplOptions.Synchronized)] public override Task<int> ReadBlockAsync(char[] buffer, int index, int count) { @@ -382,7 +373,6 @@ namespace System.IO { return Task.FromResult(ReadBlock(buffer, index, count)); } - [ComVisible(false)] [MethodImplAttribute(MethodImplOptions.Synchronized)] public override Task<int> ReadAsync(char[] buffer, int index, int count) { diff --git a/src/mscorlib/src/System/IO/TextWriter.cs b/src/mscorlib/src/System/IO/TextWriter.cs deleted file mode 100644 index 131f69d35d..0000000000 --- a/src/mscorlib/src/System/IO/TextWriter.cs +++ /dev/null @@ -1,886 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Text; -using System.Threading; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Security.Permissions; -using System.Globalization; -using System.Diagnostics.CodeAnalysis; -using System.Diagnostics.Contracts; -using System.Threading.Tasks; - -namespace System.IO { - // This abstract base class represents a writer that can write a sequential - // stream of characters. A subclass must minimally implement the - // Write(char) method. - // - // This class is intended for character output, not bytes. - // There are methods on the Stream class for writing bytes. - [Serializable] - [ComVisible(true)] - public abstract class TextWriter : MarshalByRefObject, IDisposable { - public static readonly TextWriter Null = new NullTextWriter(); - - // This should be initialized to Environment.NewLine, but - // to avoid loading Environment unnecessarily so I've duplicated - // the value here. -#if !PLATFORM_UNIX - private const String InitialNewLine = "\r\n"; - - protected char[] CoreNewLine = new char[] { '\r', '\n' }; -#else - private const String InitialNewLine = "\n"; - - protected char[] CoreNewLine = new char[] {'\n'}; -#endif // !PLATFORM_UNIX - - // Can be null - if so, ask for the Thread's CurrentCulture every time. - private IFormatProvider InternalFormatProvider; - - protected TextWriter() - { - InternalFormatProvider = null; // Ask for CurrentCulture all the time. - } - - protected TextWriter(IFormatProvider formatProvider) - { - InternalFormatProvider = formatProvider; - } - - public virtual IFormatProvider FormatProvider { - get { - if (InternalFormatProvider == null) - return Thread.CurrentThread.CurrentCulture; - else - return InternalFormatProvider; - } - } - - // Closes this TextWriter and releases any system resources associated with the - // TextWriter. Following a call to Close, any operations on the TextWriter - // may raise exceptions. This default method is empty, but descendant - // classes can override the method to provide the appropriate - // functionality. - public virtual void Close() { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - } - - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - // Clears all buffers for this TextWriter and causes any buffered data to be - // written to the underlying device. This default method is empty, but - // descendant classes can override the method to provide the appropriate - // functionality. - public virtual void Flush() { - } - - public abstract Encoding Encoding { - get; - } - - // Returns the line terminator string used by this TextWriter. The default line - // terminator string is a carriage return followed by a line feed ("\r\n"). - // - // Sets the line terminator string for this TextWriter. The line terminator - // string is written to the text stream whenever one of the - // WriteLine methods are called. In order for text written by - // the TextWriter to be readable by a TextReader, only one of the following line - // terminator strings should be used: "\r", "\n", or "\r\n". - // - public virtual String NewLine { - get { return new String(CoreNewLine); } - set { - if (value == null) - value = InitialNewLine; - CoreNewLine = value.ToCharArray(); - } - } - - - public static TextWriter Synchronized(TextWriter writer) { - if (writer==null) - throw new ArgumentNullException(nameof(writer)); - Contract.Ensures(Contract.Result<TextWriter>() != null); - Contract.EndContractBlock(); - - if (writer is SyncTextWriter) - return writer; - - return new SyncTextWriter(writer); - } - - // Writes a character to the text stream. This default method is empty, - // but descendant classes can override the method to provide the - // appropriate functionality. - // - public virtual void Write(char value) { - } - - // Writes a character array to the text stream. This default method calls - // Write(char) for each of the characters in the character array. - // If the character array is null, nothing is written. - // - public virtual void Write(char[] buffer) { - if (buffer != null) Write(buffer, 0, buffer.Length); - } - - // Writes a range of a character array to the text stream. This method will - // write count characters of data into this TextWriter from the - // buffer character array starting at position index. - // - public virtual void Write(char[] buffer, int index, int count) { - if (buffer==null) - throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer")); - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - if (buffer.Length - index < count) - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); - Contract.EndContractBlock(); - - for (int i = 0; i < count; i++) Write(buffer[index + i]); - } - - // Writes the text representation of a boolean to the text stream. This - // method outputs either Boolean.TrueString or Boolean.FalseString. - // - public virtual void Write(bool value) { - Write(value ? Boolean.TrueLiteral : Boolean.FalseLiteral); - } - - // Writes the text representation of an integer to the text stream. The - // text representation of the given value is produced by calling the - // Int32.ToString() method. - // - public virtual void Write(int value) { - Write(value.ToString(FormatProvider)); - } - - // Writes the text representation of an integer to the text stream. The - // text representation of the given value is produced by calling the - // UInt32.ToString() method. - // - [CLSCompliant(false)] - public virtual void Write(uint value) { - Write(value.ToString(FormatProvider)); - } - - // Writes the text representation of a long to the text stream. The - // text representation of the given value is produced by calling the - // Int64.ToString() method. - // - public virtual void Write(long value) { - Write(value.ToString(FormatProvider)); - } - - // Writes the text representation of an unsigned long to the text - // stream. The text representation of the given value is produced - // by calling the UInt64.ToString() method. - // - [CLSCompliant(false)] - public virtual void Write(ulong value) { - Write(value.ToString(FormatProvider)); - } - - // Writes the text representation of a float to the text stream. The - // text representation of the given value is produced by calling the - // Float.toString(float) method. - // - public virtual void Write(float value) { - Write(value.ToString(FormatProvider)); - } - - // Writes the text representation of a double to the text stream. The - // text representation of the given value is produced by calling the - // Double.toString(double) method. - // - public virtual void Write(double value) { - Write(value.ToString(FormatProvider)); - } - - public virtual void Write(Decimal value) { - Write(value.ToString(FormatProvider)); - } - - // Writes a string to the text stream. If the given string is null, nothing - // is written to the text stream. - // - public virtual void Write(String value) { - if (value != null) Write(value.ToCharArray()); - } - - // Writes the text representation of an object to the text stream. If the - // given object is null, nothing is written to the text stream. - // Otherwise, the object's ToString method is called to produce the - // string representation, and the resulting string is then written to the - // output stream. - // - public virtual void Write(Object value) { - if (value != null) { - IFormattable f = value as IFormattable; - if (f != null) - Write(f.ToString(null, FormatProvider)); - else - Write(value.ToString()); - } - } - -#if false - // // Converts the wchar * to a string and writes this to the stream. - // // - // __attribute NonCLSCompliantAttribute() - // public void Write(wchar *value) { - // Write(new String(value)); - // } - - // // Treats the byte* as a LPCSTR, converts it to a string, and writes it to the stream. - // // - // __attribute NonCLSCompliantAttribute() - // public void Write(byte *value) { - // Write(new String(value)); - // } -#endif - - - // Writes out a formatted string. Uses the same semantics as - // String.Format. - // - public virtual void Write(String format, Object arg0) - { - Write(String.Format(FormatProvider, format, arg0)); - } - - // Writes out a formatted string. Uses the same semantics as - // String.Format. - // - public virtual void Write(String format, Object arg0, Object arg1) - { - Write(String.Format(FormatProvider, format, arg0, arg1)); - } - - // Writes out a formatted string. Uses the same semantics as - // String.Format. - // - public virtual void Write(String format, Object arg0, Object arg1, Object arg2) - { - Write(String.Format(FormatProvider, format, arg0, arg1, arg2)); - } - - // Writes out a formatted string. Uses the same semantics as - // String.Format. - // - public virtual void Write(String format, params Object[] arg) - { - Write(String.Format(FormatProvider, format, arg)); - } - - - // Writes a line terminator to the text stream. The default line terminator - // is a carriage return followed by a line feed ("\r\n"), but this value - // can be changed by setting the NewLine property. - // - public virtual void WriteLine() { - Write(CoreNewLine); - } - - // Writes a character followed by a line terminator to the text stream. - // - public virtual void WriteLine(char value) { - Write(value); - WriteLine(); - } - - // Writes an array of characters followed by a line terminator to the text - // stream. - // - public virtual void WriteLine(char[] buffer) { - Write(buffer); - WriteLine(); - } - - // Writes a range of a character array followed by a line terminator to the - // text stream. - // - public virtual void WriteLine(char[] buffer, int index, int count) { - Write(buffer, index, count); - WriteLine(); - } - - // Writes the text representation of a boolean followed by a line - // terminator to the text stream. - // - public virtual void WriteLine(bool value) { - Write(value); - WriteLine(); - } - - // Writes the text representation of an integer followed by a line - // terminator to the text stream. - // - public virtual void WriteLine(int value) { - Write(value); - WriteLine(); - } - - // Writes the text representation of an unsigned integer followed by - // a line terminator to the text stream. - // - [CLSCompliant(false)] - public virtual void WriteLine(uint value) { - Write(value); - WriteLine(); - } - - // Writes the text representation of a long followed by a line terminator - // to the text stream. - // - public virtual void WriteLine(long value) { - Write(value); - WriteLine(); - } - - // Writes the text representation of an unsigned long followed by - // a line terminator to the text stream. - // - [CLSCompliant(false)] - public virtual void WriteLine(ulong value) { - Write(value); - WriteLine(); - } - - // Writes the text representation of a float followed by a line terminator - // to the text stream. - // - public virtual void WriteLine(float value) { - Write(value); - WriteLine(); - } - - // Writes the text representation of a double followed by a line terminator - // to the text stream. - // - public virtual void WriteLine(double value) { - Write(value); - WriteLine(); - } - - public virtual void WriteLine(decimal value) { - Write(value); - WriteLine(); - } - - // Writes a string followed by a line terminator to the text stream. - // - public virtual void WriteLine(String value) { - - if (value==null) { - WriteLine(); - } - else { - // We'd ideally like WriteLine to be atomic, in that one call - // to WriteLine equals one call to the OS (ie, so writing to - // console while simultaneously calling printf will guarantee we - // write out a string and new line chars, without any interference). - // Additionally, we need to call ToCharArray on Strings anyways, - // so allocating a char[] here isn't any worse than what we were - // doing anyways. We do reduce the number of calls to the - // backing store this way, potentially. - int vLen = value.Length; - int nlLen = CoreNewLine.Length; - char[] chars = new char[vLen+nlLen]; - value.CopyTo(0, chars, 0, vLen); - // CoreNewLine will almost always be 2 chars, and possibly 1. - if (nlLen == 2) { - chars[vLen] = CoreNewLine[0]; - chars[vLen+1] = CoreNewLine[1]; - } - else if (nlLen == 1) - chars[vLen] = CoreNewLine[0]; - else - Buffer.InternalBlockCopy(CoreNewLine, 0, chars, vLen * 2, nlLen * 2); - Write(chars, 0, vLen + nlLen); - } - /* - Write(value); // We could call Write(String) on StreamWriter... - WriteLine(); - */ - } - - // Writes the text representation of an object followed by a line - // terminator to the text stream. - // - public virtual void WriteLine(Object value) { - if (value==null) { - WriteLine(); - } - else { - // Call WriteLine(value.ToString), not Write(Object), WriteLine(). - // This makes calls to WriteLine(Object) atomic. - IFormattable f = value as IFormattable; - if (f != null) - WriteLine(f.ToString(null, FormatProvider)); - else - WriteLine(value.ToString()); - } - } - - // Writes out a formatted string and a new line. Uses the same - // semantics as String.Format. - // - public virtual void WriteLine(String format, Object arg0) - { - WriteLine(String.Format(FormatProvider, format, arg0)); - } - - // Writes out a formatted string and a new line. Uses the same - // semantics as String.Format. - // - public virtual void WriteLine (String format, Object arg0, Object arg1) - { - WriteLine(String.Format(FormatProvider, format, arg0, arg1)); - } - - // Writes out a formatted string and a new line. Uses the same - // semantics as String.Format. - // - public virtual void WriteLine (String format, Object arg0, Object arg1, Object arg2) - { - WriteLine(String.Format(FormatProvider, format, arg0, arg1, arg2)); - } - - // Writes out a formatted string and a new line. Uses the same - // semantics as String.Format. - // - public virtual void WriteLine (String format, params Object[] arg) - { - WriteLine(String.Format(FormatProvider, format, arg)); - } - - #region Task based Async APIs - [ComVisible(false)] - public virtual Task WriteAsync(char value) - { - var tuple = new Tuple<TextWriter, char>(this, value); - return Task.Factory.StartNew(state => - { - var t = (Tuple<TextWriter, char>)state; - t.Item1.Write(t.Item2); - }, - tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); - } - - [ComVisible(false)] - public virtual Task WriteAsync(String value) - { - var tuple = new Tuple<TextWriter, string>(this, value); - return Task.Factory.StartNew(state => - { - var t = (Tuple<TextWriter, string>)state; - t.Item1.Write(t.Item2); - }, - tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); - } - - [ComVisible(false)] - public Task WriteAsync(char[] buffer) - { - if (buffer == null) return Task.CompletedTask; - return WriteAsync(buffer, 0, buffer.Length); - } - - [ComVisible(false)] - public virtual Task WriteAsync(char[] buffer, int index, int count) - { - var tuple = new Tuple<TextWriter, char[], int, int>(this, buffer, index, count); - return Task.Factory.StartNew(state => - { - var t = (Tuple<TextWriter, char[], int, int>)state; - t.Item1.Write(t.Item2, t.Item3, t.Item4); - }, - tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); - } - - [ComVisible(false)] - public virtual Task WriteLineAsync(char value) - { - var tuple = new Tuple<TextWriter, char>(this, value); - return Task.Factory.StartNew(state => - { - var t = (Tuple<TextWriter, char>)state; - t.Item1.WriteLine(t.Item2); - }, - tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); - } - - [ComVisible(false)] - public virtual Task WriteLineAsync(String value) - { - var tuple = new Tuple<TextWriter, string>(this, value); - return Task.Factory.StartNew(state => - { - var t = (Tuple<TextWriter, string>)state; - t.Item1.WriteLine(t.Item2); - }, - tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); - } - - [ComVisible(false)] - public Task WriteLineAsync(char[] buffer) - { - if (buffer == null) return Task.CompletedTask; - return WriteLineAsync(buffer, 0, buffer.Length); - } - - [ComVisible(false)] - public virtual Task WriteLineAsync(char[] buffer, int index, int count) - { - var tuple = new Tuple<TextWriter, char[], int, int>(this, buffer, index, count); - return Task.Factory.StartNew(state => - { - var t = (Tuple<TextWriter, char[], int, int>)state; - t.Item1.WriteLine(t.Item2, t.Item3, t.Item4); - }, - tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); - } - - [ComVisible(false)] - public virtual Task WriteLineAsync() - { - return WriteAsync(CoreNewLine); - } - - [ComVisible(false)] - public virtual Task FlushAsync() - { - return Task.Factory.StartNew(state => - { - ((TextWriter)state).Flush(); - }, - this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); - } - #endregion - - [Serializable] - private sealed class NullTextWriter : TextWriter - { - internal NullTextWriter(): base(CultureInfo.InvariantCulture) { - } - - public override Encoding Encoding { - get { return Encoding.Default; } - } - - [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. - public override void Write(char[] buffer, int index, int count) { - } - - public override void Write(String value) { - } - - // Not strictly necessary, but for perf reasons - public override void WriteLine() { - } - - // Not strictly necessary, but for perf reasons - public override void WriteLine(String value) { - } - - public override void WriteLine(Object value) { - } - } - - [Serializable] - internal sealed class SyncTextWriter : TextWriter, IDisposable - { - private TextWriter _out; - - internal SyncTextWriter(TextWriter t): base(t.FormatProvider) { - _out = t; - } - - public override Encoding Encoding { - get { return _out.Encoding; } - } - - public override IFormatProvider FormatProvider { - get { return _out.FormatProvider; } - } - - public override String NewLine { - [MethodImplAttribute(MethodImplOptions.Synchronized)] - get { return _out.NewLine; } - [MethodImplAttribute(MethodImplOptions.Synchronized)] - set { _out.NewLine = value; } - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Close() { - // So that any overriden Close() gets run - _out.Close(); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - protected override void Dispose(bool disposing) { - // Explicitly pick up a potentially methodimpl'ed Dispose - if (disposing) - ((IDisposable)_out).Dispose(); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Flush() { - _out.Flush(); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(char value) { - _out.Write(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(char[] buffer) { - _out.Write(buffer); - } - - [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(char[] buffer, int index, int count) { - _out.Write(buffer, index, count); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(bool value) { - _out.Write(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(int value) { - _out.Write(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(uint value) { - _out.Write(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(long value) { - _out.Write(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(ulong value) { - _out.Write(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(float value) { - _out.Write(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(double value) { - _out.Write(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(Decimal value) { - _out.Write(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(String value) { - _out.Write(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(Object value) { - _out.Write(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(String format, Object arg0) { - _out.Write(format, arg0); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(String format, Object arg0, Object arg1) { - _out.Write(format, arg0, arg1); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(String format, Object arg0, Object arg1, Object arg2) { - _out.Write(format, arg0, arg1, arg2); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void Write(String format, Object[] arg) { - _out.Write(format, arg); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine() { - _out.WriteLine(); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(char value) { - _out.WriteLine(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(decimal value) { - _out.WriteLine(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(char[] buffer) { - _out.WriteLine(buffer); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(char[] buffer, int index, int count) { - _out.WriteLine(buffer, index, count); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(bool value) { - _out.WriteLine(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(int value) { - _out.WriteLine(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(uint value) { - _out.WriteLine(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(long value) { - _out.WriteLine(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(ulong value) { - _out.WriteLine(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(float value) { - _out.WriteLine(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(double value) { - _out.WriteLine(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(String value) { - _out.WriteLine(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(Object value) { - _out.WriteLine(value); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(String format, Object arg0) { - _out.WriteLine(format, arg0); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(String format, Object arg0, Object arg1) { - _out.WriteLine(format, arg0, arg1); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(String format, Object arg0, Object arg1, Object arg2) { - _out.WriteLine(format, arg0, arg1, arg2); - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public override void WriteLine(String format, Object[] arg) { - _out.WriteLine(format, arg); - } - - - // - // On SyncTextWriter all APIs should run synchronously, even the async ones. - // - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - [ComVisible(false)] - public override Task WriteAsync(char value) - { - Write(value); - return Task.CompletedTask; - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - [ComVisible(false)] - public override Task WriteAsync(String value) - { - Write(value); - return Task.CompletedTask; - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - [ComVisible(false)] - public override Task WriteAsync(char[] buffer, int index, int count) - { - Write(buffer, index, count); - return Task.CompletedTask; - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - [ComVisible(false)] - public override Task WriteLineAsync(char value) - { - WriteLine(value); - return Task.CompletedTask; - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - [ComVisible(false)] - public override Task WriteLineAsync(String value) - { - WriteLine(value); - return Task.CompletedTask; - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - [ComVisible(false)] - public override Task WriteLineAsync(char[] buffer, int index, int count) - { - WriteLine(buffer, index, count); - return Task.CompletedTask; - } - - [MethodImplAttribute(MethodImplOptions.Synchronized)] - [ComVisible(false)] - public override Task FlushAsync() - { - Flush(); - return Task.CompletedTask; - } - } - } -} diff --git a/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs b/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs index 4208ebfb6d..f3fd71833c 100644 --- a/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs +++ b/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs @@ -17,7 +17,6 @@ using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.Versioning; -using System.Security.Permissions; using Microsoft.Win32.SafeHandles; using System.Diagnostics; using System.Diagnostics.Contracts; diff --git a/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs b/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs index d78632639b..165b6d2b19 100644 --- a/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs +++ b/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs @@ -17,7 +17,6 @@ using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; -using System.Security.Permissions; using System.Threading; using System.Diagnostics; using System.Diagnostics.Contracts; @@ -108,25 +107,14 @@ namespace System.IO { } public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length) { - Initialize(buffer, offset, length, FileAccess.Read, false); + Initialize(buffer, offset, length, FileAccess.Read); } public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access) { - Initialize(buffer, offset, length, access, false); - } - - // We must create one of these without doing a security check. This - // class is created while security is trying to start up. Plus, doing - // a Demand from Assembly.GetManifestResourceStream isn't useful. - internal UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck) { - Initialize(buffer, offset, length, access, skipSecurityCheck); + Initialize(buffer, offset, length, access); } protected void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access) { - Initialize(buffer, offset, length, access, false); - } - - internal void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } @@ -147,11 +135,6 @@ namespace System.IO { if (_isOpen) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice")); } - if (!skipSecurityCheck) { -#pragma warning disable 618 - new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); -#pragma warning restore 618 - } // check for wraparound unsafe { @@ -181,31 +164,18 @@ namespace System.IO { [CLSCompliant(false)] public unsafe UnmanagedMemoryStream(byte* pointer, long length) { - Initialize(pointer, length, length, FileAccess.Read, false); + Initialize(pointer, length, length, FileAccess.Read); } [CLSCompliant(false)] public unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access) { - Initialize(pointer, length, capacity, access, false); - } - - // We must create one of these without doing a security check. This - // class is created while security is trying to start up. Plus, doing - // a Demand from Assembly.GetManifestResourceStream isn't useful. - internal unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access, bool skipSecurityCheck) - { - Initialize(pointer, length, capacity, access, skipSecurityCheck); + Initialize(pointer, length, capacity, access); } [CLSCompliant(false)] protected unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access) { - Initialize(pointer, length, capacity, access, false); - } - - internal unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access, bool skipSecurityCheck) - { if (pointer == null) throw new ArgumentNullException(nameof(pointer)); if (length < 0 || capacity < 0) @@ -221,12 +191,6 @@ namespace System.IO { if (_isOpen) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice")); - if (!skipSecurityCheck) { -#pragma warning disable 618 - new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); -#pragma warning restore 618 - } - _mem = pointer; _offset = 0; _length = length; @@ -265,7 +229,6 @@ namespace System.IO { if (!_isOpen) __Error.StreamIsClosed(); } - [ComVisible(false)] public override Task FlushAsync(CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) @@ -421,7 +384,6 @@ namespace System.IO { return nInt; } - [ComVisible(false)] public override Task<Int32> ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) { if (buffer==null) throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer")); @@ -618,7 +580,6 @@ namespace System.IO { return; } - [ComVisible(false)] public override Task WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) { if (buffer==null) diff --git a/src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs b/src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs index 040ddbb3d7..99b257ea56 100644 --- a/src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs +++ b/src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs @@ -13,7 +13,6 @@ using System; using System.Runtime.InteropServices; -using System.Security.Permissions; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Threading; diff --git a/src/mscorlib/src/System/IO/__Error.cs b/src/mscorlib/src/System/IO/__Error.cs index ad4972de54..955ddbec63 100644 --- a/src/mscorlib/src/System/IO/__Error.cs +++ b/src/mscorlib/src/System/IO/__Error.cs @@ -21,7 +21,6 @@ using Win32Native = Microsoft.Win32.Win32Native; using System.Text; using System.Globalization; using System.Security; -using System.Security.Permissions; using System.Diagnostics.Contracts; namespace System.IO { @@ -51,10 +50,6 @@ namespace System.IO { internal static void ReadNotSupported() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream")); } - - internal static void SeekNotSupported() { - throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnseekableStream")); - } internal static void WrongAsyncResult() { throw new ArgumentException(Environment.GetResourceString("Arg_WrongAsyncResult")); @@ -187,34 +182,11 @@ namespace System.IO { throw new IOException(Win32Native.GetMessage(errorCode), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath); } } - - // An alternative to WinIOError with friendlier messages for drives - internal static void WinIODriveError(String driveName) { - int errorCode = Marshal.GetLastWin32Error(); - WinIODriveError(driveName, errorCode); - } - - internal static void WinIODriveError(String driveName, int errorCode) - { - switch (errorCode) { - case Win32Native.ERROR_PATH_NOT_FOUND: - case Win32Native.ERROR_INVALID_DRIVE: - throw new DriveNotFoundException(Environment.GetResourceString("IO.DriveNotFound_Drive", driveName)); - - default: - WinIOError(errorCode, driveName); - break; - } - } internal static void WriteNotSupported() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnwritableStream")); } - internal static void WriterClosed() { - throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_WriterClosed")); - } - // From WinError.h internal const int ERROR_FILE_NOT_FOUND = Win32Native.ERROR_FILE_NOT_FOUND; internal const int ERROR_PATH_NOT_FOUND = Win32Native.ERROR_PATH_NOT_FOUND; |