//#define COSMOSDEBUG using System; using System.Collections.Generic; using System.IO; using Cosmos.System.FileSystem.Listing; namespace Cosmos.System.FileSystem.VFS { /// /// VFSManager (Virtual File System Manager) class. Used to manage files and directories. /// public static class VFSManager { private static VFSBase mVFS; /// /// Register VFS. Initialize the VFS. /// /// A VFS to register. /// Thrown if VFS already registered / memory error. /// Thrown on I/O exception. /// Thrown on memory error. /// Thrown on memory error. /// Thrown on memory error. /// Thrown on memory error. /// Thrown on fatal error. /// Thrown on fatal error. /// Thrown on memory error. /// Thrown on fatal error. public static void RegisterVFS(VFSBase aVFS) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.RegisterVFS ---"); if (mVFS != null) { throw new Exception("Virtual File System Manager already initialized!"); } aVFS.Initialize(); mVFS = aVFS; } /// /// Create a file. /// /// A path to the file. /// DirectoryEntry value. /// Thrown if aPath is null. /// Thrown if aPath is empty or contains invalid chars. /// /// /// Thrown when the entry at aPath is not a file. /// Thrown when the parent directory of aPath is not a directory. /// /// /// Thrown when aPath is longer than the system defined max lenght. public static DirectoryEntry CreateFile(string aPath) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.CreateFile ---"); if (string.IsNullOrEmpty(aPath)) { throw new ArgumentNullException(nameof(aPath)); } Global.mFileSystemDebugger.SendInternal("aPath ="); Global.mFileSystemDebugger.SendInternal(aPath); return mVFS.CreateFile(aPath); } /// /// Delete a file. /// /// A path to the file. /// /// /// Thrown if VFS manager is null. /// The entry at aPath is not a file. /// /// /// Thrown when the specified path isn't a file public static void DeleteFile(string aPath) { if (mVFS == null) throw new Exception("VFSManager isn't ready."); var xFile = mVFS.GetFile(aPath); if (xFile.mEntryType != DirectoryEntryTypeEnum.File) throw new UnauthorizedAccessException("The specified path isn't a file"); mVFS.DeleteFile(xFile); } /// /// Get file. /// /// A path to the file. /// DirectoryEntry value. /// /// /// Thrown if aPath is null / empty / invalid. /// Root path is null or empty. /// Memory error. /// Fatal error. /// /// /// /// /// Thrown if aPath is null or empty. /// Filesystem is null. /// Root directory is null. /// Memory error. /// /// /// /// /// Thrown when root directory address is smaller then root directory address. /// Memory error. /// /// /// /// /// Thrown when aPath is too deep. /// Data lenght is greater then Int32.MaxValue. /// /// /// /// /// Thrown when unable to determine filesystem for path: + aPath. /// data size invalid. /// invalid directory entry type. /// path not found. /// /// /// Thrown on memory error. public static DirectoryEntry GetFile(string aPath) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetFile ---"); if (string.IsNullOrEmpty(aPath)) { throw new ArgumentNullException(nameof(aPath)); } Global.mFileSystemDebugger.SendInternal("aPath ="); Global.mFileSystemDebugger.SendInternal(aPath); string xFileName = Path.GetFileName(aPath); Global.mFileSystemDebugger.SendInternal("xFileName ="); Global.mFileSystemDebugger.SendInternal(xFileName); string xDirectory = aPath.Remove(aPath.Length - xFileName.Length); Global.mFileSystemDebugger.SendInternal("xDirectory ="); Global.mFileSystemDebugger.SendInternal(xDirectory); char xLastChar = xDirectory[xDirectory.Length - 1]; if (xLastChar != Path.DirectorySeparatorChar) { xDirectory = xDirectory + Path.DirectorySeparatorChar; } var xList = GetDirectoryListing(xDirectory); for (int i = 0; i < xList.Count; i++) { var xEntry = xList[i]; if ((xEntry != null) && (xEntry.mEntryType == DirectoryEntryTypeEnum.File) && (xEntry.mName.ToUpper() == xFileName.ToUpper())) { return xEntry; } } return null; } /// /// Create directory. /// /// A path to the directory. /// DirectoryEntry value. /// /// /// Thrown if aPath is null / empty / invalid. /// memory error. /// /// /// Thrown on memory error / unknown directory entry type. /// Thrown when data lenght is greater then Int32.MaxValue. /// /// /// Thrown when data size invalid. /// invalid directory entry type. /// the entry at aPath is not a directory. /// memory error. /// /// /// /// /// Thrown if aPath length is zero. /// Thrown if aPath is invalid. /// memory error. /// /// /// Thrown on memory error. /// Thrown on fatal error (contact support). /// Thrown on fatal error (contact support). /// Thrown on memory error. /// Thrown when The aPath is longer than the system defined maximum length. public static DirectoryEntry CreateDirectory(string aPath) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.CreateDirectory ---"); if (string.IsNullOrEmpty(aPath)) { throw new ArgumentNullException(nameof(aPath)); } Global.mFileSystemDebugger.SendInternal("aPath ="); Global.mFileSystemDebugger.SendInternal(aPath); return mVFS.CreateDirectory(aPath); } /// /// Delete directory. /// /// A path to the directory. /// Recursive delete (not empty directory). /// /// /// Thrown if aPath is null or empty. /// Memory error. /// Fatal error. /// /// /// /// /// Thrown if VFSManager is null. /// Root directory is null. /// Memory error. /// /// /// /// /// Thrown when root directory address is smaller then root directory address. /// Memory error. /// /// /// /// /// Thrown when aPath is too deep. /// Data lenght is greater then Int32.MaxValue. /// /// /// /// /// Thrown if VFSManager is null. /// Thrown when unable to determine filesystem for path: + aPath. /// data size invalid. /// invalid directory entry type. /// path not found. /// /// /// Thrown on memory error. /// Thrown if specified path isn't a directory / trying to delete not empty directory not recursivly / directory contains a corrupted file. /// Thrown when trying to delete unknown type entry. public static void DeleteDirectory(string aPath, bool recursive) { if (mVFS == null) { throw new Exception("VFSManager isn't ready."); } var xDirectory = mVFS.GetDirectory(aPath); var xDirectoryListing = mVFS.GetDirectoryListing(xDirectory); if (xDirectory.mEntryType != DirectoryEntryTypeEnum.Directory) { throw new IOException("The specified path isn't a directory"); } if (xDirectoryListing.Count > 0 && !recursive) { throw new IOException("Directory is not empty"); } if (recursive) { foreach (var entry in xDirectoryListing) { if (entry.mEntryType == DirectoryEntryTypeEnum.Directory) { DeleteDirectory(entry.mFullPath, true); } else if (entry.mEntryType == DirectoryEntryTypeEnum.File) { DeleteFile(entry.mFullPath); } else { throw new IOException("The directory contains a corrupted file"); } } } mVFS.DeleteDirectory(xDirectory); } /// /// Get directory. /// /// A path to the directory. /// DirectoryEntry value. /// /// /// Thrown if aPath is null or empty. /// Root path is null or empty. /// Memory error. /// Fatal error. /// /// /// /// /// Thrown if VFSManager is null. /// Thrown if aPath is null. /// Root directory is null. /// Memory error. /// /// /// /// /// Thrown when root directory address is smaller then root directory address. /// Memory error. /// /// /// /// /// Thrown when aPath is too deep. /// Data lenght is greater then Int32.MaxValue. /// /// /// /// /// Thrown when unable to determine filesystem for path: + aPath. /// data size invalid. /// invalid directory entry type. /// path not found. /// /// /// Thrown on memory error. public static DirectoryEntry GetDirectory(string aPath) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetDirectory ---"); if (string.IsNullOrEmpty(aPath)) { throw new ArgumentNullException(nameof(aPath)); } Global.mFileSystemDebugger.SendInternal("aPath ="); Global.mFileSystemDebugger.SendInternal(aPath); return mVFS.GetDirectory(aPath); } /// /// Get directory listing. /// /// A path to the entry. /// DirectoryEntry list value. /// /// /// Thrown if aPath is null or empty. /// Root path is null or empty. /// Memory error. /// Fatal error. /// /// /// /// /// Thrown if aPath is null or empty. /// Filesystem is null. /// Root directory is null. /// Memory error. /// /// /// /// /// Thrown when root directory address is smaller then root directory address. /// Memory error. /// /// /// /// /// Thrown when aPath is too deep. /// Data lenght is greater then Int32.MaxValue. /// /// /// /// /// Thrown when unable to determine filesystem for path: + aPath. /// data size invalid. /// invalid directory entry type. /// path not found. /// /// /// Thrown on memory error. public static List GetDirectoryListing(string aPath) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetDirectoryListing ---"); if (string.IsNullOrEmpty(aPath)) { throw new ArgumentNullException(nameof(aPath)); } Global.mFileSystemDebugger.SendInternal("aPath ="); Global.mFileSystemDebugger.SendInternal(aPath); return mVFS.GetDirectoryListing(aPath); } /// /// Get volume. /// /// The volume root path. /// A directory entry for the volume. /// Thrown when aVolume is null or empty. /// Unable to determine filesystem for path: + aVolume /// Thrown if aVolume / filesystem is null. /// Thrown when root directory address is smaller then root directory address. public static DirectoryEntry GetVolume(string aVolume) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetVolume ---"); if (string.IsNullOrEmpty(aVolume)) { throw new ArgumentNullException(nameof(aVolume)); } Global.mFileSystemDebugger.SendInternal("aVolume ="); Global.mFileSystemDebugger.SendInternal(aVolume); return mVFS.GetVolume(aVolume); } /// /// Gets the volumes for all registered file systems. /// /// A list of directory entries for all volumes. /// Thrown if filesystem is null. /// Thrown when root directory address is smaller then root directory address. /// Thrown when root path is null or empty. public static List GetVolumes() { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetVolumes ---"); return mVFS.GetVolumes(); } /// /// Register file system. /// /// A file system to register. public static void RegisterFileSystem(FileSystemFactory aFileSystemFactory) { mVFS.RegisterFileSystem(aFileSystemFactory); } /// /// Get logical drivers list. /// /// List of strings value. /// Thrown if filesystem is null. /// Thrown when root directory address is smaller then root directory address. /// Thrown when root path is null or empty. public static List GetLogicalDrives() { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetLogicalDrives ---"); List xDrives = new List(); foreach (DirectoryEntry entry in GetVolumes()) xDrives.Add(entry.mName + Path.VolumeSeparatorChar + Path.DirectorySeparatorChar); return xDrives; } /// /// Get file directory names. /// Not implemented. /// /// unused. /// unused. /// unused. /// unused. /// unused. /// unused. /// null. public static List InternalGetFileDirectoryNames( string path, string userPathOriginal, string searchPattern, bool includeFiles, bool includeDirs, SearchOption searchOption) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.InternalGetFileDirectoryNames ---"); return null; /* //TODO: Add SearchOption functionality //TODO: What is userPathOriginal? //TODO: Add SearchPattern functionality List xFileAndDirectoryNames = new List(); //Validate input arguments if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories)) throw new ArgumentOutOfRangeException("searchOption"); searchPattern = searchPattern.TrimEnd(new char[0]); if (searchPattern.Length == 0) return new string[0]; //Perform search in filesystem FilesystemEntry[] xEntries = GetDirectoryListing(path); foreach (FilesystemEntry xEntry in xEntries) { if (xEntry.IsDirectory && includeDirs) xFileAndDirectoryNames.Add(xEntry.Name); else if (!xEntry.IsDirectory && includeFiles) xFileAndDirectoryNames.Add(xEntry.Name); } return xFileAndDirectoryNames.ToArray(); */ } /// /// Check if file exists. /// /// A path to the file. /// bool value. public static bool FileExists(string aPath) { Global.mFileSystemDebugger.SendInternal("VFSManager.FileExists"); if (aPath == null) { return false; } try { Global.mFileSystemDebugger.SendInternal("aPath ="); Global.mFileSystemDebugger.SendInternal(aPath); string xPath = Path.GetFullPath(aPath); Global.mFileSystemDebugger.SendInternal("After GetFullPath"); Global.mFileSystemDebugger.SendInternal("xPath ="); Global.mFileSystemDebugger.SendInternal(xPath); return GetFile(xPath) != null; } catch (Exception e) { global::System.Console.Write("Exception occurred: "); global::System.Console.WriteLine(e.Message); return false; } } /// /// Check if file exists. /// /// A entry of the file. /// bool value. public static bool FileExists(DirectoryEntry aEntry) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.FileExists ---"); if (aEntry == null) { return false; } try { Global.mFileSystemDebugger.SendInternal("aEntry.mName ="); Global.mFileSystemDebugger.SendInternal(aEntry.mName); string xPath = GetFullPath(aEntry); Global.mFileSystemDebugger.SendInternal("After GetFullPath"); Global.mFileSystemDebugger.SendInternal("xPath ="); Global.mFileSystemDebugger.SendInternal(xPath); return GetFile(xPath) != null; } catch { /* Simply map any Exception to false as this method should return only bool */ return false; } } /// /// Check if directory exists. /// /// A path to the directory. /// bool value. /// Thrown when aPath is null or empty. public static bool DirectoryExists(string aPath) { if (String.IsNullOrEmpty(aPath)) { throw new ArgumentException("Argument is null or empty", nameof(aPath)); } Global.mFileSystemDebugger.SendInternal("--- VFSManager.DirectoryExists ---"); try { Global.mFileSystemDebugger.SendInternal("aPath = " + aPath); string xPath = Path.GetFullPath(aPath); Global.mFileSystemDebugger.SendInternal("After GetFullPath"); Global.mFileSystemDebugger.SendInternal("xPath ="); Global.mFileSystemDebugger.SendInternal(xPath); return GetDirectory(xPath) != null; } catch { /* Simply map any Exception to false as this method should return only bool */ return false; } } /// /// Check if directory exists. /// /// A entry of the directory. /// bool value. /// Thrown when aEntry is null. public static bool DirectoryExists(DirectoryEntry aEntry) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.DirectoryExists ---"); if (aEntry == null) { throw new ArgumentNullException(nameof(aEntry)); } try { Global.mFileSystemDebugger.SendInternal("aEntry.mName ="); Global.mFileSystemDebugger.SendInternal(aEntry.mName); string xPath = GetFullPath(aEntry); Global.mFileSystemDebugger.SendInternal("After GetFullPath"); Global.mFileSystemDebugger.SendInternal("xPath ="); Global.mFileSystemDebugger.SendInternal(xPath); return GetDirectory(xPath) != null; } catch (Exception e) { global::System.Console.Write("Exception occurred: "); global::System.Console.WriteLine(e.Message); return false; } } /// /// Get full path to the entry. /// /// A entry. /// string value. /// Thrown when aEntry is null. public static string GetFullPath(DirectoryEntry aEntry) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetFullPath ---"); if (aEntry == null) { throw new ArgumentNullException(nameof(aEntry)); } Global.mFileSystemDebugger.SendInternal("aEntry.mName ="); Global.mFileSystemDebugger.SendInternal(aEntry.mName); var xParent = aEntry.mParent; string xPath = aEntry.mName; while (xParent != null) { xPath = xParent.mName + xPath; Global.mFileSystemDebugger.SendInternal("xPath ="); Global.mFileSystemDebugger.SendInternal(xPath); xParent = xParent.mParent; Global.mFileSystemDebugger.SendInternal("xParent.mName ="); Global.mFileSystemDebugger.SendInternal(xParent.mName); } Global.mFileSystemDebugger.SendInternal("xPath ="); Global.mFileSystemDebugger.SendInternal(xPath); return xPath; } /// /// Get file stream. /// /// A path to the file. /// Stream value. /// /// /// Thrown if aPathname is null / empty / invalid. /// Root path is null or empty. /// Memory error. /// Fatal error. /// /// /// /// /// Thrown if aPathname is null or empty. /// Filesystem is null. /// Root directory is null. /// Memory error. /// /// /// /// /// Thrown when root directory address is smaller then root directory address. /// Memory error. /// /// /// /// /// Thrown when aPathname is too deep. /// Data lenght is greater then Int32.MaxValue. /// The number of clusters in the FAT entry is greater than Int32.MaxValue. /// /// /// /// /// Thrown when unable to determine filesystem for path: + aPathname. /// data size invalid. /// invalid directory entry type. /// path not found. /// FAT table not found. /// memory error. /// /// /// Thrown on memory error. public static Stream GetFileStream(string aPathname) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetFileStream ---"); if (string.IsNullOrEmpty(aPathname)) { return null; } Global.mFileSystemDebugger.SendInternal("aPathName ="); Global.mFileSystemDebugger.SendInternal(aPathname); var xFileInfo = GetFile(aPathname); if (xFileInfo == null) { throw new Exception("File not found: " + aPathname); } return xFileInfo.GetFileStream(); } /// /// Get file attributes. /// /// A path to the file /// FileAttributes value. /// /// /// Thrown if aPath is null or empty. /// Thrown when aFS root path is null or empty. /// Thrown on memory error. /// Fatal error. /// /// /// /// /// Thrown if VFSManager is null. /// Thrown when root directory is null. /// Thrown on memory error. /// /// /// /// /// Thrown when root directory address is smaller then root directory address. /// Thrown on memory error. /// /// /// /// /// Thrown when aPath is too deep. /// Thrown when data lenght is greater then Int32.MaxValue. /// /// /// /// /// Thrown when data size invalid. /// Thrown on invalid directory entry type. /// Thrown when aPath entry not found. /// Thrown when unable to determine filesystem for path: + aPath. /// Thrown aPath is neither a file neither a directory. /// /// /// Thrown on memory error. public static FileAttributes GetFileAttributes(string aPath) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetFileAttributes ---"); return mVFS.GetFileAttributes(aPath); } /// /// Sets the attributes for a File / Directory. /// Not implemented. /// /// The path of the File / Directory. /// The attributes of the File / Directory. /// Thrown always public static void SetFileAttributes(string aPath, FileAttributes fileAttributes) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetFileAttributes ---"); mVFS.SetFileAttributes(aPath, fileAttributes); } /// /// Check if drive id is valid. /// /// Drive id to check. /// bool value. /// Thrown if aPath length is smaller then 2, or greater than Int32.MaxValue. public static bool IsValidDriveId(string aPath) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetFileAttributes ---"); return mVFS.IsValidDriveId(aPath); } /// /// Get total size in bytes. /// /// A drive id to get the size of. /// long value. /// Thrown when aDriveId is null or empty. /// Unable to determine filesystem for path: + aDriveId public static long GetTotalSize(string aDriveId) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetTotalSize ---"); return mVFS.GetTotalSize(aDriveId); } /// /// Get available free space. /// /// A drive id to get the size of. /// long value. /// Thrown when aDriveId is null or empty. /// Unable to determine filesystem for path: + aDriveId public static long GetAvailableFreeSpace(string aDriveId) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetAvailableFreeSpace ---"); return mVFS.GetAvailableFreeSpace(aDriveId); } /// /// Get total free space. /// /// A drive id to get the size of. /// long value. /// Thrown when aDriveId is null or empty. /// Unable to determine filesystem for path: + aDriveId public static long GetTotalFreeSpace(string aDriveId) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetTotalFreeSpace ---"); return mVFS.GetTotalFreeSpace(aDriveId); } /// /// Get file system type. /// /// A drive id. /// string value. /// Thrown when aDriveId is null or empty. /// Unable to determine filesystem for path: + aDriveId public static string GetFileSystemType(string aDriveId) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetFileSystemType ---"); return mVFS.GetFileSystemType(aDriveId); } /// /// Get file system label. /// /// A drive id. /// string value. /// Thrown when aDriveId is null or empty. /// Unable to determine filesystem for path: + aDriveId public static string GetFileSystemLabel(string aDriveId) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetFileSystemLabel ---"); return mVFS.GetFileSystemLabel(aDriveId); } /// /// Set file system type. /// /// A drive id. /// A label to be set. /// Thrown when aDriveId is null or empty. /// Unable to determine filesystem for path: + aDriveId public static void SetFileSystemLabel(string aDriveId, string aLabel) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.SetFileSystemLabel ---"); mVFS.SetFileSystemLabel(aDriveId, aLabel); } /// /// Format partition. /// /// A drive id. /// A drive format. /// Quick format. /// /// /// Thrown when the data length is 0 or greater then Int32.MaxValue. /// Entrys matadata offset value is invalid. /// Fatal error (contact support). /// /// /// Thrown when filesystem is null / memory error. /// /// /// Thrown when aDriveId is null or empty. /// Data length is 0. /// Root path is null or empty. /// Memory error. /// /// /// /// /// Unable to determine filesystem for path: + aDriveId. /// Thrown when data size invalid. /// Thrown on unknown file system type. /// Thrown on fatal error (contact support). /// /// /// Thrown when data lenght is greater then Int32.MaxValue. /// Thrown on memory error. /// Thrown when FAT type is unknown. /// Thrown on fatal error (contact support). /// Thrown on fatal error (contact support). /// Thrown when the data in aData is corrupted. /// Thrown when FAT type is unknown. public static void Format(string aDriveId, string aDriveFormat, bool aQuick) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.Format ---"); mVFS.Format(aDriveId, aDriveFormat, aQuick); } #region Helpers /// /// Get alt. directory separator char. /// /// char value. public static char GetAltDirectorySeparatorChar() { return '/'; } /// /// Get directory separator char. /// /// char value. public static char GetDirectorySeparatorChar() { return '\\'; } /// /// Get invalid filename chars. /// /// char array value. public static char[] GetInvalidFileNameChars() { char[] xReturn = { '"', '<', '>', '|', '\0', '\a', '\b', '\t', '\n', '\v', '\f', '\r', ':', '*', '?', '\\', '/' }; return xReturn; } /// /// Get invalid path chars with additional checks. /// /// char array value. public static char[] GetInvalidPathCharsWithAdditionalChecks() { char[] xReturn = { '"', '<', '>', '|', '\0', '\a', '\b', '\t', '\n', '\v', '\f', '\r', '*', '?' }; return xReturn; } /// /// Get path separator char. /// /// char value. public static char GetPathSeparator() { return ';'; } /// /// Get real invalid path chars. /// /// char array value. public static char[] GetRealInvalidPathChars() { char[] xReturn = { '"', '<', '>', '|' }; return xReturn; } /// /// Get trim end chars. /// /// char array value. public static char[] GetTrimEndChars() { char[] xReturn = { (char) 0x9, (char) 0xA, (char) 0xB, (char) 0xC, (char) 0xD, (char) 0x20, (char) 0x85, (char) 0xA0 }; return xReturn; } /// /// Get volume separator char. /// /// char value. public static char GetVolumeSeparatorChar() { return ':'; } /// /// Get max path. /// /// int value. public static int GetMaxPath() { return 260; } //public static bool IsAbsolutePath(this string aPath) //{ // return ((aPath[0] == VFSBase.DirectorySeparatorChar) || (aPath[0] == VFSBase.AltDirectorySeparatorChar)); //} //public static bool IsRelativePath(this string aPath) //{ // return (aPath[0] != VFSBase.DirectorySeparatorChar || aPath[0] != VFSBase.AltDirectorySeparatorChar); //} /// /// Split path. /// /// A path to split. /// string array. /// Thrown on fatal error. public static string[] SplitPath(string aPath) { //TODO: This should call Path.GetDirectoryName() and then loop calling Directory.GetParent(), but those aren't implemented yet. return aPath.Split(GetDirectorySeparators(), StringSplitOptions.RemoveEmptyEntries); } /// /// Get directory separators. /// /// char array value. private static char[] GetDirectorySeparators() { return new[] { GetDirectorySeparatorChar(), GetAltDirectorySeparatorChar() }; } #endregion Helpers /// /// Gets the parent directory entry from the path. /// /// The full path to the current directory entry. /// The parent directory entry. /// /// /// Thrown if aPath is null / empty / invalid. /// Root path is null or empty. /// Memory error. /// Fatal error. /// /// /// /// /// Thrown if VFSManager is null. /// Thrown if aPath is null. /// Root directory is null. /// Memory error. /// /// /// /// /// Thrown when root directory address is smaller then root directory address. /// Memory error. /// Fatal error. /// /// /// /// /// Thrown when aPath is too deep. /// Data lenght is greater then Int32.MaxValue. /// /// /// /// /// Thrown when unable to determine filesystem for path: + aPath. /// data size invalid. /// invalid directory entry type. /// path not found. /// /// /// Thrown on memory error. public static DirectoryEntry GetParent(string aPath) { Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetParent ---"); if (string.IsNullOrEmpty(aPath)) { throw new ArgumentException("Argument is null or empty", nameof(aPath)); } Global.mFileSystemDebugger.SendInternal("aPath ="); Global.mFileSystemDebugger.SendInternal(aPath); if (aPath == Path.GetPathRoot(aPath)) { return null; } string xFileOrDirectory = Path.HasExtension(aPath) ? Path.GetFileName(aPath) : Path.GetDirectoryName(aPath); if (xFileOrDirectory != null) { string xPath = aPath.Remove(aPath.Length - xFileOrDirectory.Length); return GetDirectory(xPath); } return null; } } }