mirror of
https://github.com/ReneLergner/WPinternals.git
synced 2026-08-10 18:11:14 +10:00
Initial commit - WPinternals 2.6
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
//
|
||||
// Copyright (c) 2008-2011, Kenneth Bell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace DiscUtils.Vfs
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Interface implemented by classes representing a directory.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDirEntry">Concrete type representing directory entries.</typeparam>
|
||||
/// <typeparam name="TFile">Concrete type representing files.</typeparam>
|
||||
public interface IVfsDirectory<TDirEntry, TFile> : IVfsFile
|
||||
where TDirEntry : VfsDirEntry
|
||||
where TFile : IVfsFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets all of the directory entries.
|
||||
/// </summary>
|
||||
ICollection<TDirEntry> AllEntries { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a self-reference, if available.
|
||||
/// </summary>
|
||||
TDirEntry Self
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a specific directory entry, by name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the directory entry.</param>
|
||||
/// <returns>The directory entry, or <c>null</c> if not found.</returns>
|
||||
TDirEntry GetEntryByName(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new file.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the file (relative to this directory).</param>
|
||||
/// <returns>The newly created file.</returns>
|
||||
TDirEntry CreateNewFile(string name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// Copyright (c) 2008-2011, Kenneth Bell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace DiscUtils.Vfs
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// Interface implemented by a class representing a file.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// File system implementations should have a class that implements this
|
||||
/// interface. If the file system implementation is read-only, it is
|
||||
/// acceptable to throw <c>NotImplementedException</c> from setters.
|
||||
/// </remarks>
|
||||
public interface IVfsFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the last access time in UTC.
|
||||
/// </summary>
|
||||
DateTime LastAccessTimeUtc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the last write time in UTC.
|
||||
/// </summary>
|
||||
DateTime LastWriteTimeUtc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the last creation time in UTC.
|
||||
/// </summary>
|
||||
DateTime CreationTimeUtc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the file's attributes.
|
||||
/// </summary>
|
||||
FileAttributes FileAttributes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the file.
|
||||
/// </summary>
|
||||
long FileLength { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a buffer to access the file's contents.
|
||||
/// </summary>
|
||||
IBuffer FileContent { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface implemented by classes representing files, in file systems that support multi-stream files.
|
||||
/// </summary>
|
||||
public interface IVfsFileWithStreams : IVfsFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new stream.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the stream.</param>
|
||||
/// <returns>An object representing the stream.</returns>
|
||||
SparseStream CreateStream(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Opens an existing stream.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the stream.</param>
|
||||
/// <returns>An object representing the stream.</returns>
|
||||
/// <remarks>The implementation must not implicitly create the stream if it doesn't already
|
||||
/// exist.</remarks>
|
||||
SparseStream OpenExistingStream(string name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (c) 2008-2011, Kenneth Bell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace DiscUtils.Vfs
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface implemented by classes representing a directory.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDirEntry">Concrete type representing directory entries.</typeparam>
|
||||
/// <typeparam name="TFile">Concrete type representing files.</typeparam>
|
||||
public interface IVfsSymlink<TDirEntry, TFile> : IVfsFile
|
||||
where TDirEntry : VfsDirEntry
|
||||
where TFile : IVfsFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the target path for this symlink.
|
||||
/// </summary>
|
||||
string TargetPath { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Copyright (c) 2008-2011, Kenneth Bell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace DiscUtils.Vfs
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for a context object that holds global state for file system implementations.
|
||||
/// </summary>
|
||||
public abstract class VfsContext
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// Copyright (c) 2008-2011, Kenneth Bell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace DiscUtils.Vfs
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for directory entries in a file system.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// File system implementations should have a class that derives from
|
||||
/// this abstract class. If the file system implementation is read-only,
|
||||
/// it is acceptable to throw <c>NotImplementedException</c> from methods
|
||||
/// that attempt to modify the file system.
|
||||
/// </remarks>
|
||||
public abstract class VfsDirEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this directory entry represents a directory (rather than a file).
|
||||
/// </summary>
|
||||
public abstract bool IsDirectory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this directory entry represents a symlink (rather than a file or directory).
|
||||
/// </summary>
|
||||
public abstract bool IsSymlink { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of this directory entry.
|
||||
/// </summary>
|
||||
public abstract string FileName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this directory entry contains time information.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Typically either always returns <c>true</c> or <c>false</c>.</para>
|
||||
/// </remarks>
|
||||
public abstract bool HasVfsTimeInfo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last access time of the file or directory.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// May throw <c>NotSupportedException</c> if <c>HasVfsTimeInfo</c> is <c>false</c>.
|
||||
/// </remarks>
|
||||
public abstract DateTime LastAccessTimeUtc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last write time of the file or directory.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// May throw <c>NotSupportedException</c> if <c>HasVfsTimeInfo</c> is <c>false</c>.
|
||||
/// </remarks>
|
||||
public abstract DateTime LastWriteTimeUtc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the creation time of the file or directory.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// May throw <c>NotSupportedException</c> if <c>HasVfsTimeInfo</c> is <c>false</c>.
|
||||
/// </remarks>
|
||||
public abstract DateTime CreationTimeUtc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this directory entry contains file attribute information.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Typically either always returns <c>true</c> or <c>false</c>.</para>
|
||||
/// </remarks>
|
||||
public abstract bool HasVfsFileAttributes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file attributes from the directory entry.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// May throw <c>NotSupportedException</c> if <c>HasVfsFileAttributes</c> is <c>false</c>.
|
||||
/// </remarks>
|
||||
public abstract FileAttributes FileAttributes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a unique id for the file or directory represented by this directory entry.
|
||||
/// </summary>
|
||||
public abstract long UniqueCacheId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a version of FileName that can be used in wildcard matches.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The returned name, must have an extension separator '.', and not have any optional version
|
||||
/// information found in some files. The returned name is matched against a wildcard patterns
|
||||
/// such as "*.*".
|
||||
/// </remarks>
|
||||
public virtual string SearchName
|
||||
{
|
||||
get
|
||||
{
|
||||
string fileName = FileName;
|
||||
if (fileName.IndexOf('.') == -1)
|
||||
{
|
||||
return fileName + ".";
|
||||
}
|
||||
else
|
||||
{
|
||||
return fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,772 @@
|
||||
//
|
||||
// Copyright (c) 2008-2011, Kenneth Bell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace DiscUtils.Vfs
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for VFS file systems.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDirEntry">The concrete type representing directory entries.</typeparam>
|
||||
/// <typeparam name="TFile">The concrete type representing files.</typeparam>
|
||||
/// <typeparam name="TDirectory">The concrete type representing directories.</typeparam>
|
||||
/// <typeparam name="TContext">The concrete type holding global state.</typeparam>
|
||||
public abstract class VfsFileSystem<TDirEntry, TFile, TDirectory, TContext> : DiscFileSystem
|
||||
where TDirEntry : VfsDirEntry
|
||||
where TFile : IVfsFile
|
||||
where TDirectory : class, IVfsDirectory<TDirEntry, TFile>, TFile
|
||||
where TContext : VfsContext
|
||||
{
|
||||
private TContext _context;
|
||||
private TDirectory _rootDir;
|
||||
private ObjectCache<long, TFile> _fileCache;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the VfsFileSystem class.
|
||||
/// </summary>
|
||||
/// <param name="defaultOptions">The default file system options.</param>
|
||||
protected VfsFileSystem(DiscFileSystemOptions defaultOptions)
|
||||
: base(defaultOptions)
|
||||
{
|
||||
_fileCache = new ObjectCache<long, TFile>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for processing directory entries.
|
||||
/// </summary>
|
||||
/// <param name="path">Full path to the directory entry.</param>
|
||||
/// <param name="dirEntry">The directory entry itself.</param>
|
||||
protected delegate void DirEntryHandler(string path, TDirEntry dirEntry);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the volume label.
|
||||
/// </summary>
|
||||
public override abstract string VolumeLabel
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the global shared state.
|
||||
/// </summary>
|
||||
protected TContext Context
|
||||
{
|
||||
get { return _context; }
|
||||
set { _context = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the object representing the root directory.
|
||||
/// </summary>
|
||||
protected TDirectory RootDirectory
|
||||
{
|
||||
get { return _rootDir; }
|
||||
set { _rootDir = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a file - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="sourceFile">The source file.</param>
|
||||
/// <param name="destinationFile">The destination file.</param>
|
||||
/// <param name="overwrite">Whether to permit over-writing of an existing file.</param>
|
||||
public override void CopyFile(string sourceFile, string destinationFile, bool overwrite)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a directory - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the new directory.</param>
|
||||
public override void CreateDirectory(string path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a directory - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the directory to delete.</param>
|
||||
public override void DeleteDirectory(string path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a file - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file to delete.</param>
|
||||
public override void DeleteFile(string path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if a directory exists.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to test.</param>
|
||||
/// <returns>true if the directory exists.</returns>
|
||||
public override bool DirectoryExists(string path)
|
||||
{
|
||||
if (IsRoot(path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
TDirEntry dirEntry = GetDirectoryEntry(path);
|
||||
|
||||
if (dirEntry != null)
|
||||
{
|
||||
return dirEntry.IsDirectory;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if a file exists.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to test.</param>
|
||||
/// <returns>true if the file exists.</returns>
|
||||
public override bool FileExists(string path)
|
||||
{
|
||||
TDirEntry dirEntry = GetDirectoryEntry(path);
|
||||
|
||||
if (dirEntry != null)
|
||||
{
|
||||
return !dirEntry.IsDirectory;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of subdirectories in a specified directory matching a specified
|
||||
/// search pattern, using a value to determine whether to search subdirectories.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to search.</param>
|
||||
/// <param name="searchPattern">The search string to match against.</param>
|
||||
/// <param name="searchOption">Indicates whether to search subdirectories.</param>
|
||||
/// <returns>Array of directories matching the search pattern.</returns>
|
||||
public override string[] GetDirectories(string path, string searchPattern, SearchOption searchOption)
|
||||
{
|
||||
Regex re = Utilities.ConvertWildcardsToRegEx(searchPattern);
|
||||
|
||||
List<string> dirs = new List<string>();
|
||||
DoSearch(dirs, path, re, searchOption == SearchOption.AllDirectories, true, false);
|
||||
return dirs.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of files in a specified directory matching a specified
|
||||
/// search pattern, using a value to determine whether to search subdirectories.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to search.</param>
|
||||
/// <param name="searchPattern">The search string to match against.</param>
|
||||
/// <param name="searchOption">Indicates whether to search subdirectories.</param>
|
||||
/// <returns>Array of files matching the search pattern.</returns>
|
||||
public override string[] GetFiles(string path, string searchPattern, SearchOption searchOption)
|
||||
{
|
||||
Regex re = Utilities.ConvertWildcardsToRegEx(searchPattern);
|
||||
|
||||
List<string> results = new List<string>();
|
||||
DoSearch(results, path, re, searchOption == SearchOption.AllDirectories, false, true);
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of all files and subdirectories in a specified directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to search.</param>
|
||||
/// <returns>Array of files and subdirectories matching the search pattern.</returns>
|
||||
public override string[] GetFileSystemEntries(string path)
|
||||
{
|
||||
string fullPath = path;
|
||||
if (!fullPath.StartsWith(@"\", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
fullPath = @"\" + fullPath;
|
||||
}
|
||||
|
||||
TDirectory parentDir = GetDirectory(fullPath);
|
||||
return Utilities.Map<TDirEntry, string>(parentDir.AllEntries, (m) => Utilities.CombinePaths(fullPath, FormatFileName(m.FileName)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of files and subdirectories in a specified directory matching a specified
|
||||
/// search pattern.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to search.</param>
|
||||
/// <param name="searchPattern">The search string to match against.</param>
|
||||
/// <returns>Array of files and subdirectories matching the search pattern.</returns>
|
||||
public override string[] GetFileSystemEntries(string path, string searchPattern)
|
||||
{
|
||||
Regex re = Utilities.ConvertWildcardsToRegEx(searchPattern);
|
||||
|
||||
TDirectory parentDir = GetDirectory(path);
|
||||
|
||||
List<string> result = new List<string>();
|
||||
foreach (TDirEntry dirEntry in parentDir.AllEntries)
|
||||
{
|
||||
if (re.IsMatch(dirEntry.SearchName))
|
||||
{
|
||||
result.Add(Utilities.CombinePaths(path, dirEntry.FileName));
|
||||
}
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves a directory.
|
||||
/// </summary>
|
||||
/// <param name="sourceDirectoryName">The directory to move.</param>
|
||||
/// <param name="destinationDirectoryName">The target directory name.</param>
|
||||
public override void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves a file.
|
||||
/// </summary>
|
||||
/// <param name="sourceName">The file to move.</param>
|
||||
/// <param name="destinationName">The target file name.</param>
|
||||
/// <param name="overwrite">Overwrite any existing file.</param>
|
||||
public override void MoveFile(string sourceName, string destinationName, bool overwrite)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the specified file.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the file to open.</param>
|
||||
/// <param name="mode">The file mode for the created stream.</param>
|
||||
/// <param name="access">The access permissions for the created stream.</param>
|
||||
/// <returns>The new stream.</returns>
|
||||
public override SparseStream OpenFile(string path, FileMode mode, FileAccess access)
|
||||
{
|
||||
if (!CanWrite)
|
||||
{
|
||||
if (mode != FileMode.Open)
|
||||
{
|
||||
throw new NotSupportedException("Only existing files can be opened");
|
||||
}
|
||||
|
||||
if (access != FileAccess.Read)
|
||||
{
|
||||
throw new NotSupportedException("Files cannot be opened for write");
|
||||
}
|
||||
}
|
||||
|
||||
string fileName = Utilities.GetFileFromPath(path);
|
||||
string attributeName = null;
|
||||
|
||||
int streamSepPos = fileName.IndexOf(':');
|
||||
if (streamSepPos >= 0)
|
||||
{
|
||||
attributeName = fileName.Substring(streamSepPos + 1);
|
||||
}
|
||||
|
||||
string dirName;
|
||||
try
|
||||
{
|
||||
dirName = Utilities.GetDirectoryFromPath(path);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
throw new IOException("Invalid path: " + path);
|
||||
}
|
||||
|
||||
string entryPath = Utilities.CombinePaths(dirName, fileName);
|
||||
TDirEntry entry = GetDirectoryEntry(entryPath);
|
||||
if (entry == null)
|
||||
{
|
||||
if (mode == FileMode.Open)
|
||||
{
|
||||
throw new FileNotFoundException("No such file", path);
|
||||
}
|
||||
else
|
||||
{
|
||||
TDirectory parentDir = GetDirectory(Utilities.GetDirectoryFromPath(path));
|
||||
entry = parentDir.CreateNewFile(Utilities.GetFileFromPath(path));
|
||||
}
|
||||
}
|
||||
else if (mode == FileMode.CreateNew)
|
||||
{
|
||||
throw new IOException("File already exists");
|
||||
}
|
||||
|
||||
if (entry.IsSymlink)
|
||||
{
|
||||
entry = ResolveSymlink(entry, entryPath);
|
||||
}
|
||||
|
||||
if (entry.IsDirectory)
|
||||
{
|
||||
throw new IOException("Attempt to open directory as a file");
|
||||
}
|
||||
else
|
||||
{
|
||||
TFile file = GetFile(entry);
|
||||
|
||||
SparseStream stream = null;
|
||||
if (string.IsNullOrEmpty(attributeName))
|
||||
{
|
||||
stream = new BufferStream(file.FileContent, access);
|
||||
}
|
||||
else
|
||||
{
|
||||
IVfsFileWithStreams fileStreams = file as IVfsFileWithStreams;
|
||||
if (fileStreams != null)
|
||||
{
|
||||
stream = fileStreams.OpenExistingStream(attributeName);
|
||||
if (stream == null)
|
||||
{
|
||||
if (mode == FileMode.Create || mode == FileMode.OpenOrCreate)
|
||||
{
|
||||
stream = fileStreams.CreateStream(attributeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FileNotFoundException("No such attribute on file", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("Attempt to open a file stream on a file system that doesn't support them");
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == FileMode.Create || mode == FileMode.Truncate)
|
||||
{
|
||||
stream.SetLength(0);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the attributes of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The file or directory to inspect.</param>
|
||||
/// <returns>The attributes of the file or directory.</returns>
|
||||
public override FileAttributes GetAttributes(string path)
|
||||
{
|
||||
if (IsRoot(path))
|
||||
{
|
||||
return _rootDir.FileAttributes;
|
||||
}
|
||||
|
||||
TDirEntry dirEntry = GetDirectoryEntry(path);
|
||||
if (dirEntry == null)
|
||||
{
|
||||
throw new FileNotFoundException("File not found", path);
|
||||
}
|
||||
|
||||
if (dirEntry.HasVfsFileAttributes)
|
||||
{
|
||||
return dirEntry.FileAttributes;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFile(dirEntry).FileAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the attributes of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The file or directory to change.</param>
|
||||
/// <param name="newValue">The new attributes of the file or directory.</param>
|
||||
public override void SetAttributes(string path, FileAttributes newValue)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the creation time (in UTC) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <returns>The creation time.</returns>
|
||||
public override DateTime GetCreationTimeUtc(string path)
|
||||
{
|
||||
if (IsRoot(path))
|
||||
{
|
||||
return _rootDir.CreationTimeUtc;
|
||||
}
|
||||
|
||||
TDirEntry dirEntry = GetDirectoryEntry(path);
|
||||
if (dirEntry == null)
|
||||
{
|
||||
throw new FileNotFoundException("No such file or directory", path);
|
||||
}
|
||||
|
||||
if (dirEntry.HasVfsTimeInfo)
|
||||
{
|
||||
return dirEntry.CreationTimeUtc;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFile(dirEntry).CreationTimeUtc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the creation time (in UTC) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <param name="newTime">The new time to set.</param>
|
||||
public override void SetCreationTimeUtc(string path, DateTime newTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last access time (in UTC) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <returns>The last access time.</returns>
|
||||
public override DateTime GetLastAccessTimeUtc(string path)
|
||||
{
|
||||
if (IsRoot(path))
|
||||
{
|
||||
return _rootDir.LastAccessTimeUtc;
|
||||
}
|
||||
|
||||
TDirEntry dirEntry = GetDirectoryEntry(path);
|
||||
if (dirEntry == null)
|
||||
{
|
||||
throw new FileNotFoundException("No such file or directory", path);
|
||||
}
|
||||
|
||||
if (dirEntry.HasVfsTimeInfo)
|
||||
{
|
||||
return dirEntry.LastAccessTimeUtc;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFile(dirEntry).LastAccessTimeUtc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the last access time (in UTC) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <param name="newTime">The new time to set.</param>
|
||||
public override void SetLastAccessTimeUtc(string path, DateTime newTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last modification time (in UTC) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <returns>The last write time.</returns>
|
||||
public override DateTime GetLastWriteTimeUtc(string path)
|
||||
{
|
||||
if (IsRoot(path))
|
||||
{
|
||||
return _rootDir.LastWriteTimeUtc;
|
||||
}
|
||||
|
||||
TDirEntry dirEntry = GetDirectoryEntry(path);
|
||||
if (dirEntry == null)
|
||||
{
|
||||
throw new FileNotFoundException("No such file or directory", path);
|
||||
}
|
||||
|
||||
if (dirEntry.HasVfsTimeInfo)
|
||||
{
|
||||
return dirEntry.LastWriteTimeUtc;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFile(dirEntry).LastWriteTimeUtc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the last modification time (in UTC) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <param name="newTime">The new time to set.</param>
|
||||
public override void SetLastWriteTimeUtc(string path, DateTime newTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of a file.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the file.</param>
|
||||
/// <returns>The length in bytes.</returns>
|
||||
public override long GetFileLength(string path)
|
||||
{
|
||||
TFile file = GetFile(path);
|
||||
if (file == null || (file.FileAttributes & FileAttributes.Directory) != 0)
|
||||
{
|
||||
throw new FileNotFoundException("No such file", path);
|
||||
}
|
||||
|
||||
return file.FileLength;
|
||||
}
|
||||
|
||||
internal TFile GetFile(TDirEntry dirEntry)
|
||||
{
|
||||
long cacheKey = dirEntry.UniqueCacheId;
|
||||
|
||||
TFile file = _fileCache[cacheKey];
|
||||
if (file == null)
|
||||
{
|
||||
file = ConvertDirEntryToFile(dirEntry);
|
||||
_fileCache[cacheKey] = file;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
internal TDirectory GetDirectory(string path)
|
||||
{
|
||||
if (IsRoot(path))
|
||||
{
|
||||
return _rootDir;
|
||||
}
|
||||
|
||||
TDirEntry dirEntry = GetDirectoryEntry(path);
|
||||
|
||||
if (dirEntry.IsSymlink)
|
||||
{
|
||||
dirEntry = ResolveSymlink(dirEntry, path);
|
||||
}
|
||||
|
||||
if (dirEntry == null || !dirEntry.IsDirectory)
|
||||
{
|
||||
throw new DirectoryNotFoundException("No such directory: " + path);
|
||||
}
|
||||
|
||||
return (TDirectory)GetFile(dirEntry);
|
||||
}
|
||||
|
||||
internal TDirEntry GetDirectoryEntry(string path)
|
||||
{
|
||||
return GetDirectoryEntry(_rootDir, path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all directory entries in the specified directory and sub-directories.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to inspect.</param>
|
||||
/// <param name="handler">Delegate invoked for each directory entry.</param>
|
||||
protected void ForAllDirEntries(string path, DirEntryHandler handler)
|
||||
{
|
||||
TDirectory dir = null;
|
||||
TDirEntry self = GetDirectoryEntry(path);
|
||||
|
||||
if (self != null)
|
||||
{
|
||||
handler(path, self);
|
||||
if (self.IsDirectory)
|
||||
{
|
||||
dir = GetFile(self) as TDirectory;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = GetFile(path) as TDirectory;
|
||||
}
|
||||
|
||||
if (dir != null)
|
||||
{
|
||||
foreach (var subentry in dir.AllEntries)
|
||||
{
|
||||
ForAllDirEntries(Utilities.CombinePaths(path, subentry.FileName), handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file object for a given path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to query.</param>
|
||||
/// <returns>The file object corresponding to the path.</returns>
|
||||
protected TFile GetFile(string path)
|
||||
{
|
||||
if (IsRoot(path))
|
||||
{
|
||||
return _rootDir;
|
||||
}
|
||||
else if (path == null)
|
||||
{
|
||||
return default(TFile);
|
||||
}
|
||||
|
||||
TDirEntry dirEntry = GetDirectoryEntry(path);
|
||||
if (dirEntry == null)
|
||||
{
|
||||
throw new FileNotFoundException("No such file or directory", path);
|
||||
}
|
||||
|
||||
return GetFile(dirEntry);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a directory entry to an object representing a file.
|
||||
/// </summary>
|
||||
/// <param name="dirEntry">The directory entry to convert.</param>
|
||||
/// <returns>The corresponding file object.</returns>
|
||||
protected abstract TFile ConvertDirEntryToFile(TDirEntry dirEntry);
|
||||
|
||||
/// <summary>
|
||||
/// Converts an internal directory entry name into an external one.
|
||||
/// </summary>
|
||||
/// <param name="name">The name to convert.</param>
|
||||
/// <returns>The external name.</returns>
|
||||
/// <remarks>
|
||||
/// This method is called on a single path element (i.e. name contains no path
|
||||
/// separators).
|
||||
/// </remarks>
|
||||
protected virtual string FormatFileName(string name)
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
private static bool IsRoot(string path)
|
||||
{
|
||||
return string.IsNullOrEmpty(path) || path == @"\";
|
||||
}
|
||||
|
||||
private TDirEntry GetDirectoryEntry(TDirectory dir, string path)
|
||||
{
|
||||
string[] pathElements = path.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
return GetDirectoryEntry(dir, pathElements, 0);
|
||||
}
|
||||
|
||||
private TDirEntry GetDirectoryEntry(TDirectory dir, string[] pathEntries, int pathOffset)
|
||||
{
|
||||
TDirEntry entry;
|
||||
|
||||
if (pathEntries.Length == 0)
|
||||
{
|
||||
return dir.Self;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = dir.GetEntryByName(pathEntries[pathOffset]);
|
||||
if (entry != null)
|
||||
{
|
||||
if (pathOffset == pathEntries.Length - 1)
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
else if (entry.IsDirectory)
|
||||
{
|
||||
return GetDirectoryEntry((TDirectory)ConvertDirEntryToFile(entry), pathEntries, pathOffset + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException(string.Format(CultureInfo.InvariantCulture, "{0} is a file, not a directory", pathEntries[pathOffset]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DoSearch(List<string> results, string path, Regex regex, bool subFolders, bool dirs, bool files)
|
||||
{
|
||||
TDirectory parentDir = GetDirectory(path);
|
||||
if (parentDir == null)
|
||||
{
|
||||
throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, "The directory '{0}' was not found", path));
|
||||
}
|
||||
|
||||
string resultPrefixPath = path;
|
||||
if (IsRoot(path))
|
||||
{
|
||||
resultPrefixPath = @"\";
|
||||
}
|
||||
|
||||
foreach (TDirEntry de in parentDir.AllEntries)
|
||||
{
|
||||
bool isDir = de.IsDirectory;
|
||||
|
||||
if ((isDir && dirs) || (!isDir && files))
|
||||
{
|
||||
if (regex.IsMatch(de.SearchName))
|
||||
{
|
||||
results.Add(Utilities.CombinePaths(resultPrefixPath, FormatFileName(de.FileName)));
|
||||
}
|
||||
}
|
||||
|
||||
if (subFolders && isDir)
|
||||
{
|
||||
DoSearch(results, Utilities.CombinePaths(resultPrefixPath, FormatFileName(de.FileName)), regex, subFolders, dirs, files);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TDirEntry ResolveSymlink(TDirEntry entry, string path)
|
||||
{
|
||||
TDirEntry currentEntry = entry;
|
||||
string currentPath = path;
|
||||
|
||||
int resolvesLeft = 20;
|
||||
while (currentEntry.IsSymlink && resolvesLeft > 0)
|
||||
{
|
||||
IVfsSymlink<TDirEntry, TFile> symlink = GetFile(currentEntry) as IVfsSymlink<TDirEntry, TFile>;
|
||||
if (symlink == null)
|
||||
{
|
||||
throw new FileNotFoundException("Unable to resolve symlink", path);
|
||||
}
|
||||
|
||||
currentPath = Utilities.ResolvePath(currentPath.TrimEnd('\\'), symlink.TargetPath);
|
||||
currentEntry = GetDirectoryEntry(currentPath);
|
||||
if (currentEntry == null)
|
||||
{
|
||||
throw new FileNotFoundException("Unable to resolve symlink", path);
|
||||
}
|
||||
|
||||
--resolvesLeft;
|
||||
}
|
||||
|
||||
if (currentEntry.IsSymlink)
|
||||
{
|
||||
throw new FileNotFoundException("Unable to resolve symlink - too many links", path);
|
||||
}
|
||||
|
||||
return currentEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,541 @@
|
||||
//
|
||||
// Copyright (c) 2008-2011, Kenneth Bell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace DiscUtils.Vfs
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for the public facade on a file system.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The derived class can extend the functionality available from a file system
|
||||
/// beyond that defined by DiscFileSystem.
|
||||
/// </remarks>
|
||||
public abstract class VfsFileSystemFacade : DiscFileSystem
|
||||
{
|
||||
private DiscFileSystem _wrapped;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the VfsFileSystemFacade class.
|
||||
/// </summary>
|
||||
/// <param name="toWrap">The actual file system instance.</param>
|
||||
protected VfsFileSystemFacade(DiscFileSystem toWrap)
|
||||
{
|
||||
_wrapped = toWrap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file system options, which can be modified.
|
||||
/// </summary>
|
||||
public override DiscFileSystemOptions Options
|
||||
{
|
||||
get { return _wrapped.Options; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a friendly name for the file system.
|
||||
/// </summary>
|
||||
public override string FriendlyName
|
||||
{
|
||||
get { return _wrapped.FriendlyName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the file system is read-only or read-write.
|
||||
/// </summary>
|
||||
/// <returns>true if the file system is read-write.</returns>
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return _wrapped.CanWrite; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the root directory of the file system.
|
||||
/// </summary>
|
||||
public override DiscDirectoryInfo Root
|
||||
{
|
||||
get { return new DiscDirectoryInfo(this, string.Empty); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the volume label.
|
||||
/// </summary>
|
||||
public override string VolumeLabel
|
||||
{
|
||||
get { return _wrapped.VolumeLabel; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the file system is thread-safe.
|
||||
/// </summary>
|
||||
public override bool IsThreadSafe
|
||||
{
|
||||
get { return _wrapped.IsThreadSafe; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies an existing file to a new file.
|
||||
/// </summary>
|
||||
/// <param name="sourceFile">The source file.</param>
|
||||
/// <param name="destinationFile">The destination file.</param>
|
||||
public override void CopyFile(string sourceFile, string destinationFile)
|
||||
{
|
||||
_wrapped.CopyFile(sourceFile, destinationFile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies an existing file to a new file.
|
||||
/// </summary>
|
||||
/// <param name="sourceFile">The source file.</param>
|
||||
/// <param name="destinationFile">The destination file.</param>
|
||||
/// <param name="overwrite">Overwrite any existing file.</param>
|
||||
public override void CopyFile(string sourceFile, string destinationFile, bool overwrite)
|
||||
{
|
||||
_wrapped.CopyFile(sourceFile, destinationFile, overwrite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the new directory.</param>
|
||||
public override void CreateDirectory(string path)
|
||||
{
|
||||
_wrapped.CreateDirectory(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the directory to delete.</param>
|
||||
public override void DeleteDirectory(string path)
|
||||
{
|
||||
_wrapped.DeleteDirectory(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a directory, optionally with all descendants.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the directory to delete.</param>
|
||||
/// <param name="recursive">Determines if the all descendants should be deleted.</param>
|
||||
public override void DeleteDirectory(string path, bool recursive)
|
||||
{
|
||||
_wrapped.DeleteDirectory(path, recursive);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a file.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file to delete.</param>
|
||||
public override void DeleteFile(string path)
|
||||
{
|
||||
_wrapped.DeleteFile(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if a directory exists.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to test.</param>
|
||||
/// <returns>true if the directory exists.</returns>
|
||||
public override bool DirectoryExists(string path)
|
||||
{
|
||||
return _wrapped.DirectoryExists(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if a file exists.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to test.</param>
|
||||
/// <returns>true if the file exists.</returns>
|
||||
public override bool FileExists(string path)
|
||||
{
|
||||
return _wrapped.FileExists(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if a file or directory exists.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to test.</param>
|
||||
/// <returns>true if the file or directory exists.</returns>
|
||||
public override bool Exists(string path)
|
||||
{
|
||||
return _wrapped.Exists(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of subdirectories in a specified directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to search.</param>
|
||||
/// <returns>Array of directories.</returns>
|
||||
public override string[] GetDirectories(string path)
|
||||
{
|
||||
return _wrapped.GetDirectories(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of subdirectories in a specified directory matching a specified
|
||||
/// search pattern.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to search.</param>
|
||||
/// <param name="searchPattern">The search string to match against.</param>
|
||||
/// <returns>Array of directories matching the search pattern.</returns>
|
||||
public override string[] GetDirectories(string path, string searchPattern)
|
||||
{
|
||||
return _wrapped.GetDirectories(path, searchPattern);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of subdirectories in a specified directory matching a specified
|
||||
/// search pattern, using a value to determine whether to search subdirectories.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to search.</param>
|
||||
/// <param name="searchPattern">The search string to match against.</param>
|
||||
/// <param name="searchOption">Indicates whether to search subdirectories.</param>
|
||||
/// <returns>Array of directories matching the search pattern.</returns>
|
||||
public override string[] GetDirectories(string path, string searchPattern, SearchOption searchOption)
|
||||
{
|
||||
return _wrapped.GetDirectories(path, searchPattern, searchOption);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of files in a specified directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to search.</param>
|
||||
/// <returns>Array of files.</returns>
|
||||
public override string[] GetFiles(string path)
|
||||
{
|
||||
return _wrapped.GetFiles(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of files in a specified directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to search.</param>
|
||||
/// <param name="searchPattern">The search string to match against.</param>
|
||||
/// <returns>Array of files matching the search pattern.</returns>
|
||||
public override string[] GetFiles(string path, string searchPattern)
|
||||
{
|
||||
return _wrapped.GetFiles(path, searchPattern);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of files in a specified directory matching a specified
|
||||
/// search pattern, using a value to determine whether to search subdirectories.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to search.</param>
|
||||
/// <param name="searchPattern">The search string to match against.</param>
|
||||
/// <param name="searchOption">Indicates whether to search subdirectories.</param>
|
||||
/// <returns>Array of files matching the search pattern.</returns>
|
||||
public override string[] GetFiles(string path, string searchPattern, SearchOption searchOption)
|
||||
{
|
||||
return _wrapped.GetFiles(path, searchPattern, searchOption);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of all files and subdirectories in a specified directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to search.</param>
|
||||
/// <returns>Array of files and subdirectories matching the search pattern.</returns>
|
||||
public override string[] GetFileSystemEntries(string path)
|
||||
{
|
||||
return _wrapped.GetFileSystemEntries(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of files and subdirectories in a specified directory matching a specified
|
||||
/// search pattern.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to search.</param>
|
||||
/// <param name="searchPattern">The search string to match against.</param>
|
||||
/// <returns>Array of files and subdirectories matching the search pattern.</returns>
|
||||
public override string[] GetFileSystemEntries(string path, string searchPattern)
|
||||
{
|
||||
return _wrapped.GetFileSystemEntries(path, searchPattern);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves a directory.
|
||||
/// </summary>
|
||||
/// <param name="sourceDirectoryName">The directory to move.</param>
|
||||
/// <param name="destinationDirectoryName">The target directory name.</param>
|
||||
public override void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName)
|
||||
{
|
||||
_wrapped.MoveDirectory(sourceDirectoryName, destinationDirectoryName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves a file.
|
||||
/// </summary>
|
||||
/// <param name="sourceName">The file to move.</param>
|
||||
/// <param name="destinationName">The target file name.</param>
|
||||
public override void MoveFile(string sourceName, string destinationName)
|
||||
{
|
||||
_wrapped.MoveFile(sourceName, destinationName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves a file, allowing an existing file to be overwritten.
|
||||
/// </summary>
|
||||
/// <param name="sourceName">The file to move.</param>
|
||||
/// <param name="destinationName">The target file name.</param>
|
||||
/// <param name="overwrite">Whether to permit a destination file to be overwritten.</param>
|
||||
public override void MoveFile(string sourceName, string destinationName, bool overwrite)
|
||||
{
|
||||
_wrapped.MoveFile(sourceName, destinationName, overwrite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the specified file.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the file to open.</param>
|
||||
/// <param name="mode">The file mode for the created stream.</param>
|
||||
/// <returns>The new stream.</returns>
|
||||
public override SparseStream OpenFile(string path, FileMode mode)
|
||||
{
|
||||
return _wrapped.OpenFile(path, mode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the specified file.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the file to open.</param>
|
||||
/// <param name="mode">The file mode for the created stream.</param>
|
||||
/// <param name="access">The access permissions for the created stream.</param>
|
||||
/// <returns>The new stream.</returns>
|
||||
public override SparseStream OpenFile(string path, FileMode mode, FileAccess access)
|
||||
{
|
||||
return _wrapped.OpenFile(path, mode, access);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the attributes of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The file or directory to inspect.</param>
|
||||
/// <returns>The attributes of the file or directory.</returns>
|
||||
public override FileAttributes GetAttributes(string path)
|
||||
{
|
||||
return _wrapped.GetAttributes(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the attributes of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The file or directory to change.</param>
|
||||
/// <param name="newValue">The new attributes of the file or directory.</param>
|
||||
public override void SetAttributes(string path, FileAttributes newValue)
|
||||
{
|
||||
_wrapped.SetAttributes(path, newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the creation time (in local time) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <returns>The creation time.</returns>
|
||||
public override DateTime GetCreationTime(string path)
|
||||
{
|
||||
return _wrapped.GetCreationTime(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the creation time (in local time) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <param name="newTime">The new time to set.</param>
|
||||
public override void SetCreationTime(string path, DateTime newTime)
|
||||
{
|
||||
_wrapped.SetCreationTime(path, newTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the creation time (in UTC) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <returns>The creation time.</returns>
|
||||
public override DateTime GetCreationTimeUtc(string path)
|
||||
{
|
||||
return _wrapped.GetCreationTimeUtc(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the creation time (in UTC) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <param name="newTime">The new time to set.</param>
|
||||
public override void SetCreationTimeUtc(string path, DateTime newTime)
|
||||
{
|
||||
_wrapped.SetCreationTimeUtc(path, newTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last access time (in local time) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <returns>The last access time.</returns>
|
||||
public override DateTime GetLastAccessTime(string path)
|
||||
{
|
||||
return _wrapped.GetLastAccessTime(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the last access time (in local time) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <param name="newTime">The new time to set.</param>
|
||||
public override void SetLastAccessTime(string path, DateTime newTime)
|
||||
{
|
||||
_wrapped.SetLastAccessTime(path, newTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last access time (in UTC) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <returns>The last access time.</returns>
|
||||
public override DateTime GetLastAccessTimeUtc(string path)
|
||||
{
|
||||
return _wrapped.GetLastAccessTimeUtc(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the last access time (in UTC) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <param name="newTime">The new time to set.</param>
|
||||
public override void SetLastAccessTimeUtc(string path, DateTime newTime)
|
||||
{
|
||||
_wrapped.SetLastAccessTimeUtc(path, newTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last modification time (in local time) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <returns>The last write time.</returns>
|
||||
public override DateTime GetLastWriteTime(string path)
|
||||
{
|
||||
return _wrapped.GetLastWriteTime(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the last modification time (in local time) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <param name="newTime">The new time to set.</param>
|
||||
public override void SetLastWriteTime(string path, DateTime newTime)
|
||||
{
|
||||
_wrapped.SetLastWriteTime(path, newTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last modification time (in UTC) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <returns>The last write time.</returns>
|
||||
public override DateTime GetLastWriteTimeUtc(string path)
|
||||
{
|
||||
return _wrapped.GetLastWriteTimeUtc(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the last modification time (in UTC) of a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <param name="newTime">The new time to set.</param>
|
||||
public override void SetLastWriteTimeUtc(string path, DateTime newTime)
|
||||
{
|
||||
_wrapped.SetLastWriteTimeUtc(path, newTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of a file.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the file.</param>
|
||||
/// <returns>The length in bytes.</returns>
|
||||
public override long GetFileLength(string path)
|
||||
{
|
||||
return _wrapped.GetFileLength(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an object representing a possible file.
|
||||
/// </summary>
|
||||
/// <param name="path">The file path.</param>
|
||||
/// <returns>The representing object.</returns>
|
||||
/// <remarks>The file does not need to exist.</remarks>
|
||||
public override DiscFileInfo GetFileInfo(string path)
|
||||
{
|
||||
return new DiscFileInfo(this, path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an object representing a possible directory.
|
||||
/// </summary>
|
||||
/// <param name="path">The directory path.</param>
|
||||
/// <returns>The representing object.</returns>
|
||||
/// <remarks>The directory does not need to exist.</remarks>
|
||||
public override DiscDirectoryInfo GetDirectoryInfo(string path)
|
||||
{
|
||||
return new DiscDirectoryInfo(this, path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an object representing a possible file system object (file or directory).
|
||||
/// </summary>
|
||||
/// <param name="path">The file system path.</param>
|
||||
/// <returns>The representing object.</returns>
|
||||
/// <remarks>The file system object does not need to exist.</remarks>
|
||||
public override DiscFileSystemInfo GetFileSystemInfo(string path)
|
||||
{
|
||||
return new DiscFileSystemInfo(this, path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to the actual file system implementation.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDirEntry">The concrete type representing directory entries.</typeparam>
|
||||
/// <typeparam name="TFile">The concrete type representing files.</typeparam>
|
||||
/// <typeparam name="TDirectory">The concrete type representing directories.</typeparam>
|
||||
/// <typeparam name="TContext">The concrete type holding global state.</typeparam>
|
||||
/// <returns>The actual file system instance.</returns>
|
||||
protected VfsFileSystem<TDirEntry, TFile, TDirectory, TContext> GetRealFileSystem<TDirEntry, TFile, TDirectory, TContext>()
|
||||
where TDirEntry : VfsDirEntry
|
||||
where TFile : IVfsFile
|
||||
where TDirectory : class, IVfsDirectory<TDirEntry, TFile>, TFile
|
||||
where TContext : VfsContext
|
||||
{
|
||||
return (VfsFileSystem<TDirEntry, TFile, TDirectory, TContext>)_wrapped;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to the actual file system implementation.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The concrete type of the actual file system.</typeparam>
|
||||
/// <returns>The actual file system instance.</returns>
|
||||
protected T GetRealFileSystem<T>()
|
||||
where T : DiscFileSystem
|
||||
{
|
||||
return (T)_wrapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
//
|
||||
// Copyright (c) 2008-2011, Kenneth Bell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace DiscUtils.Vfs
|
||||
{
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for logic to detect file systems.
|
||||
/// </summary>
|
||||
public abstract class VfsFileSystemFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Detects if a stream contains any known file systems.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to inspect.</param>
|
||||
/// <returns>A list of file systems (may be empty).</returns>
|
||||
public DiscUtils.FileSystemInfo[] Detect(Stream stream)
|
||||
{
|
||||
return Detect(stream, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detects if a volume contains any known file systems.
|
||||
/// </summary>
|
||||
/// <param name="volume">The volume to inspect.</param>
|
||||
/// <returns>A list of file systems (may be empty).</returns>
|
||||
public DiscUtils.FileSystemInfo[] Detect(VolumeInfo volume)
|
||||
{
|
||||
using (Stream stream = volume.Open())
|
||||
{
|
||||
return Detect(stream, volume);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The logic for detecting file systems.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to inspect.</param>
|
||||
/// <param name="volumeInfo">Optionally, information about the volume.</param>
|
||||
/// <returns>A list of file systems detected (may be empty).</returns>
|
||||
public abstract DiscUtils.FileSystemInfo[] Detect(Stream stream, VolumeInfo volumeInfo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Copyright (c) 2008-2011, Kenneth Bell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace DiscUtils.Vfs
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
/// <summary>
|
||||
/// Attribute identifying file system factory classes.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
||||
public sealed class VfsFileSystemFactoryAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
//
|
||||
// Copyright (c) 2008-2011, Kenneth Bell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace DiscUtils.Vfs
|
||||
{
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate for instantiating a file system.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream containing the file system.</param>
|
||||
/// <param name="volumeInfo">Optional, information about the volume the file system is on.</param>
|
||||
/// <param name="parameters">Parameters for the file system.</param>
|
||||
/// <returns>A file system implementation.</returns>
|
||||
public delegate DiscFileSystem VfsFileSystemOpener(Stream stream, VolumeInfo volumeInfo, FileSystemParameters parameters);
|
||||
|
||||
/// <summary>
|
||||
/// Class holding information about a file system.
|
||||
/// </summary>
|
||||
public sealed class VfsFileSystemInfo : DiscUtils.FileSystemInfo
|
||||
{
|
||||
private string _name;
|
||||
private string _description;
|
||||
private VfsFileSystemOpener _openDelegate;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the VfsFileSystemInfo class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the file system.</param>
|
||||
/// <param name="description">A one-line description of the file system.</param>
|
||||
/// <param name="openDelegate">A delegate that can open streams as the indicated file system.</param>
|
||||
public VfsFileSystemInfo(string name, string description, VfsFileSystemOpener openDelegate)
|
||||
{
|
||||
_name = name;
|
||||
_description = description;
|
||||
_openDelegate = openDelegate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the file system.
|
||||
/// </summary>
|
||||
public override string Name
|
||||
{
|
||||
get { return _name; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a one-line description of the file system.
|
||||
/// </summary>
|
||||
public override string Description
|
||||
{
|
||||
get { return _description; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a volume using the file system.
|
||||
/// </summary>
|
||||
/// <param name="volume">The volume to access.</param>
|
||||
/// <param name="parameters">Parameters for the file system.</param>
|
||||
/// <returns>A file system instance.</returns>
|
||||
public override DiscFileSystem Open(VolumeInfo volume, FileSystemParameters parameters)
|
||||
{
|
||||
return _openDelegate(volume.Open(), volume, parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a stream using the file system.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to access.</param>
|
||||
/// <param name="parameters">Parameters for the file system.</param>
|
||||
/// <returns>A file system instance.</returns>
|
||||
public override DiscFileSystem Open(Stream stream, FileSystemParameters parameters)
|
||||
{
|
||||
return _openDelegate(stream, null, parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
//
|
||||
// Copyright (c) 2008-2011, Kenneth Bell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace DiscUtils.Vfs
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for read-only file system implementations.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDirEntry">The concrete type representing directory entries.</typeparam>
|
||||
/// <typeparam name="TFile">The concrete type representing files.</typeparam>
|
||||
/// <typeparam name="TDirectory">The concrete type representing directories.</typeparam>
|
||||
/// <typeparam name="TContext">The concrete type holding global state.</typeparam>
|
||||
public abstract class VfsReadOnlyFileSystem<TDirEntry, TFile, TDirectory, TContext> : VfsFileSystem<TDirEntry, TFile, TDirectory, TContext>
|
||||
where TDirEntry : VfsDirEntry
|
||||
where TFile : IVfsFile
|
||||
where TDirectory : class, IVfsDirectory<TDirEntry, TFile>, TFile
|
||||
where TContext : VfsContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the VfsReadOnlyFileSystem class.
|
||||
/// </summary>
|
||||
/// <param name="defaultOptions">The default file system options.</param>
|
||||
protected VfsReadOnlyFileSystem(DiscFileSystemOptions defaultOptions)
|
||||
: base(defaultOptions)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the file system is read-only or read-write.
|
||||
/// </summary>
|
||||
/// <returns>Always false.</returns>
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a file - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="sourceFile">The source file.</param>
|
||||
/// <param name="destinationFile">The destination file.</param>
|
||||
/// <param name="overwrite">Whether to permit over-writing of an existing file.</param>
|
||||
public override void CopyFile(string sourceFile, string destinationFile, bool overwrite)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a directory - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the new directory.</param>
|
||||
public override void CreateDirectory(string path)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a directory - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the directory to delete.</param>
|
||||
public override void DeleteDirectory(string path)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a file - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file to delete.</param>
|
||||
public override void DeleteFile(string path)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves a directory - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="sourceDirectoryName">The directory to move.</param>
|
||||
/// <param name="destinationDirectoryName">The target directory name.</param>
|
||||
public override void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves a file - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="sourceName">The file to move.</param>
|
||||
/// <param name="destinationName">The target file name.</param>
|
||||
/// <param name="overwrite">Whether to allow an existing file to be overwritten.</param>
|
||||
public override void MoveFile(string sourceName, string destinationName, bool overwrite)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the specified file.
|
||||
/// </summary>
|
||||
/// <param name="path">The full path of the file to open.</param>
|
||||
/// <param name="mode">The file mode for the created stream.</param>
|
||||
/// <returns>The new stream.</returns>
|
||||
public override SparseStream OpenFile(string path, FileMode mode)
|
||||
{
|
||||
return OpenFile(path, mode, FileAccess.Read);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the attributes of a file or directory - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="path">The file or directory to change.</param>
|
||||
/// <param name="newValue">The new attributes of the file or directory.</param>
|
||||
public override void SetAttributes(string path, FileAttributes newValue)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the creation time (in UTC) of a file or directory - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <param name="newTime">The new time to set.</param>
|
||||
public override void SetCreationTimeUtc(string path, DateTime newTime)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the last access time (in UTC) of a file or directory - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <param name="newTime">The new time to set.</param>
|
||||
public override void SetLastAccessTimeUtc(string path, DateTime newTime)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the last modification time (in UTC) of a file or directory - not supported on read-only file systems.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the file or directory.</param>
|
||||
/// <param name="newTime">The new time to set.</param>
|
||||
public override void SetLastWriteTimeUtc(string path, DateTime newTime)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user