Make IFileSystem implement IDisposable

This commit is contained in:
Alex Barney 2019-10-17 14:52:44 -05:00
parent d330d11de2
commit ee9bee3efb
11 changed files with 113 additions and 33 deletions

View file

@ -176,7 +176,9 @@ namespace LibHac.Fs.Accessors
{ {
// Todo: Possibly check for open files and directories // Todo: Possibly check for open files and directories
// Nintendo checks for them in DumpUnclosedAccessorList in // Nintendo checks for them in DumpUnclosedAccessorList in
// FileSystemAccessor's destructor, but doesn't do anything with it // FileSystemAccessor's destructor
FileSystem?.Dispose();
} }
} }
} }

View file

@ -0,0 +1,46 @@
namespace LibHac.Fs
{
public abstract class AttributeFileSystemBase : FileSystemBase, IAttributeFileSystem
{
protected abstract Result CreateDirectoryImpl(string path, NxFileAttributes archiveAttribute);
protected abstract Result GetFileAttributesImpl(string path, out NxFileAttributes attributes);
protected abstract Result SetFileAttributesImpl(string path, NxFileAttributes attributes);
protected abstract Result GetFileSizeImpl(out long fileSize, string path);
public Result CreateDirectory(string path, NxFileAttributes archiveAttribute)
{
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
return CreateDirectoryImpl(path, archiveAttribute);
}
public Result GetFileAttributes(string path, out NxFileAttributes attributes)
{
if (IsDisposed)
{
attributes = default;
return ResultFs.PreconditionViolation.Log();
}
return GetFileAttributesImpl(path, out attributes);
}
public Result SetFileAttributes(string path, NxFileAttributes attributes)
{
if (IsDisposed) return ResultFs.PreconditionViolation.Log();
return SetFileAttributesImpl(path, attributes);
}
public Result GetFileSize(out long fileSize, string path)
{
if (IsDisposed)
{
fileSize = default;
return ResultFs.PreconditionViolation.Log();
}
return GetFileSizeImpl(out fileSize, path);
}
}
}

View file

@ -7,7 +7,7 @@ namespace LibHac.Fs
{ {
// 0 = not disposed; 1 = disposed // 0 = not disposed; 1 = disposed
private int _disposedState; private int _disposedState;
private bool IsDisposed => _disposedState != 0; protected bool IsDisposed => _disposedState != 0;
protected abstract Result CreateDirectoryImpl(string path); protected abstract Result CreateDirectoryImpl(string path);
protected abstract Result CreateFileImpl(string path, long size, CreateFileOptions options); protected abstract Result CreateFileImpl(string path, long size, CreateFileOptions options);

View file

@ -115,6 +115,16 @@ namespace LibHac.Fs
return accessor.IsAccessLogEnabled; return accessor.IsAccessLogEnabled;
} }
internal void EnableFileSystemAccessorAccessLog(U8Span mountName)
{
if (MountTable.Find(mountName.ToString(), out FileSystemAccessor accessor).IsFailure())
{
throw new LibHacException("abort");
}
accessor.IsAccessLogEnabled = true;
}
internal bool IsEnabledHandleAccessLog(FileHandle handle) internal bool IsEnabledHandleAccessLog(FileHandle handle)
{ {
return handle.File.Parent.IsAccessLogEnabled; return handle.File.Parent.IsAccessLogEnabled;

View file

@ -6,7 +6,7 @@ namespace LibHac.Fs
/// <summary> /// <summary>
/// Provides an interface for accessing a file system. <c>/</c> is used as the path delimiter. /// Provides an interface for accessing a file system. <c>/</c> is used as the path delimiter.
/// </summary> /// </summary>
public interface IFileSystem public interface IFileSystem : IDisposable
{ {
/// <summary> /// <summary>
/// Creates or overwrites a file at the specified path. /// Creates or overwrites a file at the specified path.

View file

@ -55,8 +55,8 @@ namespace LibHac.FsService.Creators
rc = sourceFileSystem.OpenFile(out IFile saveDataFile, saveDataPath, OpenMode.ReadWrite); rc = sourceFileSystem.OpenFile(out IFile saveDataFile, saveDataPath, OpenMode.ReadWrite);
if (rc.IsFailure()) return rc; if (rc.IsFailure()) return rc;
var saveDataStorage = new FileStorage(saveDataFile); var saveDataStorage = new DisposingFileStorage(saveDataFile);
fileSystem = new SaveDataFileSystem(Keyset, saveDataStorage, IntegrityCheckLevel.ErrorOnInvalid, true); fileSystem = new SaveDataFileSystem(Keyset, saveDataStorage, IntegrityCheckLevel.ErrorOnInvalid, false);
// Todo: ISaveDataExtraDataAccessor // Todo: ISaveDataExtraDataAccessor

View file

@ -24,8 +24,6 @@ namespace LibHac.FsService
public FsPath SaveDataRootPath { get; } = default; public FsPath SaveDataRootPath { get; } = default;
public bool AutoCreateSaveData { get; private set; } public bool AutoCreateSaveData { get; private set; }
private const ulong SaveIndexerId = 0x8000000000000000;
internal FileSystemProxy(FileSystemProxyCore fsProxyCore, FileSystemClient fsClient, FileSystemServer fsServer) internal FileSystemProxy(FileSystemProxyCore fsProxyCore, FileSystemClient fsClient, FileSystemServer fsServer)
{ {
FsProxyCore = fsProxyCore; FsProxyCore = fsProxyCore;
@ -189,7 +187,7 @@ namespace LibHac.FsService
if (saveFsResult != ResultFs.PathNotFound && saveFsResult != ResultFs.TargetNotFound) return saveFsResult; if (saveFsResult != ResultFs.PathNotFound && saveFsResult != ResultFs.TargetNotFound) return saveFsResult;
if (saveDataId != SaveIndexerId) if (saveDataId != FileSystemServer.SaveIndexerId)
{ {
if (hasFixedId) if (hasFixedId)
{ {

View file

@ -6,12 +6,12 @@ namespace LibHac.FsService
{ {
public class FileSystemServer public class FileSystemServer
{ {
internal const ulong SaveDataIndexerSaveId = 0x8000000000000000; internal const ulong SaveIndexerId = 0x8000000000000000;
private FileSystemProxyCore FsProxyCore { get; } private FileSystemProxyCore FsProxyCore { get; }
/// <summary>The client instance to be used for internal operations like save indexer access.</summary> /// <summary>The client instance to be used for internal operations like save indexer access.</summary>
private FileSystemClient FsClient { get; } public FileSystemClient FsClient { get; }
private ITimeSpanGenerator Timer { get; } private ITimeSpanGenerator Timer { get; }
internal SaveDataIndexerManager SaveDataIndexerManager { get; } internal SaveDataIndexerManager SaveDataIndexerManager { get; }
@ -35,7 +35,7 @@ namespace LibHac.FsService
FsClient = new FileSystemClient(this, timer); FsClient = new FileSystemClient(this, timer);
Timer = timer; Timer = timer;
SaveDataIndexerManager = new SaveDataIndexerManager(FsClient, SaveDataIndexerSaveId); SaveDataIndexerManager = new SaveDataIndexerManager(FsClient, SaveIndexerId);
} }
/// <summary> /// <summary>

View file

@ -5,7 +5,7 @@ namespace LibHac.FsSystem
{ {
public class FileStorage : StorageBase public class FileStorage : StorageBase
{ {
private IFile BaseFile { get; } protected IFile BaseFile { get; }
public FileStorage(IFile baseFile) public FileStorage(IFile baseFile)
{ {
@ -37,4 +37,17 @@ namespace LibHac.FsSystem
return BaseFile.SetSize(size); return BaseFile.SetSize(size);
} }
} }
public class DisposingFileStorage : FileStorage
{
public DisposingFileStorage(IFile baseFile) : base(baseFile) { }
protected override void Dispose(bool disposing)
{
if (disposing)
{
BaseFile?.Dispose();
}
}
}
} }

View file

@ -6,7 +6,7 @@ using LibHac.Fs;
namespace LibHac.FsSystem namespace LibHac.FsSystem
{ {
public class LocalFileSystem : IAttributeFileSystem public class LocalFileSystem : AttributeFileSystemBase
{ {
private string BasePath { get; } private string BasePath { get; }
@ -30,7 +30,7 @@ namespace LibHac.FsSystem
return PathTools.Combine(BasePath, path); return PathTools.Combine(BasePath, path);
} }
public Result GetFileAttributes(string path, out NxFileAttributes attributes) protected override Result GetFileAttributesImpl(string path, out NxFileAttributes attributes)
{ {
attributes = default; attributes = default;
@ -49,7 +49,7 @@ namespace LibHac.FsSystem
return Result.Success; return Result.Success;
} }
public Result SetFileAttributes(string path, NxFileAttributes attributes) protected override Result SetFileAttributesImpl(string path, NxFileAttributes attributes)
{ {
string localPath = ResolveLocalPath(PathTools.Normalize(path)); string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -76,7 +76,7 @@ namespace LibHac.FsSystem
return Result.Success; return Result.Success;
} }
public Result GetFileSize(out long fileSize, string path) protected override Result GetFileSizeImpl(out long fileSize, string path)
{ {
fileSize = default; fileSize = default;
string localPath = ResolveLocalPath(PathTools.Normalize(path)); string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -87,12 +87,12 @@ namespace LibHac.FsSystem
return GetSizeInternal(out fileSize, info); return GetSizeInternal(out fileSize, info);
} }
public Result CreateDirectory(string path) protected override Result CreateDirectoryImpl(string path)
{ {
return CreateDirectory(path, NxFileAttributes.None); return CreateDirectory(path, NxFileAttributes.None);
} }
public Result CreateDirectory(string path, NxFileAttributes archiveAttribute) protected override Result CreateDirectoryImpl(string path, NxFileAttributes archiveAttribute)
{ {
string localPath = ResolveLocalPath(PathTools.Normalize(path)); string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -112,7 +112,7 @@ namespace LibHac.FsSystem
return CreateDirInternal(dir, archiveAttribute); return CreateDirInternal(dir, archiveAttribute);
} }
public Result CreateFile(string path, long size, CreateFileOptions options) protected override Result CreateFileImpl(string path, long size, CreateFileOptions options)
{ {
string localPath = ResolveLocalPath(PathTools.Normalize(path)); string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -139,7 +139,7 @@ namespace LibHac.FsSystem
} }
} }
public Result DeleteDirectory(string path) protected override Result DeleteDirectoryImpl(string path)
{ {
string localPath = ResolveLocalPath(PathTools.Normalize(path)); string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -149,7 +149,7 @@ namespace LibHac.FsSystem
return DeleteDirectoryInternal(dir, false); return DeleteDirectoryInternal(dir, false);
} }
public Result DeleteDirectoryRecursively(string path) protected override Result DeleteDirectoryRecursivelyImpl(string path)
{ {
string localPath = ResolveLocalPath(PathTools.Normalize(path)); string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -159,7 +159,7 @@ namespace LibHac.FsSystem
return DeleteDirectoryInternal(dir, true); return DeleteDirectoryInternal(dir, true);
} }
public Result CleanDirectoryRecursively(string path) protected override Result CleanDirectoryRecursivelyImpl(string path)
{ {
string localPath = ResolveLocalPath(PathTools.Normalize(path)); string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -184,7 +184,7 @@ namespace LibHac.FsSystem
return Result.Success; return Result.Success;
} }
public Result DeleteFile(string path) protected override Result DeleteFileImpl(string path)
{ {
string localPath = ResolveLocalPath(PathTools.Normalize(path)); string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -194,7 +194,7 @@ namespace LibHac.FsSystem
return DeleteFileInternal(file); return DeleteFileInternal(file);
} }
public Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode) protected override Result OpenDirectoryImpl(out IDirectory directory, string path, OpenDirectoryMode mode)
{ {
directory = default; directory = default;
string localPath = ResolveLocalPath(PathTools.Normalize(path)); string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -220,7 +220,7 @@ namespace LibHac.FsSystem
} }
} }
public Result OpenFile(out IFile file, string path, OpenMode mode) protected override Result OpenFileImpl(out IFile file, string path, OpenMode mode)
{ {
file = default; file = default;
string localPath = ResolveLocalPath(PathTools.Normalize(path)); string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -240,7 +240,7 @@ namespace LibHac.FsSystem
return Result.Success; return Result.Success;
} }
public Result RenameDirectory(string oldPath, string newPath) protected override Result RenameDirectoryImpl(string oldPath, string newPath)
{ {
oldPath = PathTools.Normalize(oldPath); oldPath = PathTools.Normalize(oldPath);
newPath = PathTools.Normalize(newPath); newPath = PathTools.Normalize(newPath);
@ -263,7 +263,7 @@ namespace LibHac.FsSystem
return RenameDirInternal(srcDir, dstDir); return RenameDirInternal(srcDir, dstDir);
} }
public Result RenameFile(string oldPath, string newPath) protected override Result RenameFileImpl(string oldPath, string newPath)
{ {
string srcLocalPath = ResolveLocalPath(PathTools.Normalize(oldPath)); string srcLocalPath = ResolveLocalPath(PathTools.Normalize(oldPath));
string dstLocalPath = ResolveLocalPath(PathTools.Normalize(newPath)); string dstLocalPath = ResolveLocalPath(PathTools.Normalize(newPath));
@ -280,7 +280,7 @@ namespace LibHac.FsSystem
return RenameFileInternal(srcFile, dstFile); return RenameFileInternal(srcFile, dstFile);
} }
public Result GetEntryType(out DirectoryEntryType entryType, string path) protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
{ {
entryType = default; entryType = default;
string localPath = ResolveLocalPath(PathTools.Normalize(path)); string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -307,7 +307,7 @@ namespace LibHac.FsSystem
return ResultFs.PathNotFound.Log(); return ResultFs.PathNotFound.Log();
} }
public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path) protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path)
{ {
timeStamp = default; timeStamp = default;
string localPath = ResolveLocalPath(PathTools.Normalize(path)); string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -324,24 +324,24 @@ namespace LibHac.FsSystem
return Result.Success; return Result.Success;
} }
public Result GetFreeSpaceSize(out long freeSpace, string path) protected override Result GetFreeSpaceSizeImpl(out long freeSpace, string path)
{ {
freeSpace = new DriveInfo(BasePath).AvailableFreeSpace; freeSpace = new DriveInfo(BasePath).AvailableFreeSpace;
return Result.Success; return Result.Success;
} }
public Result GetTotalSpaceSize(out long totalSpace, string path) protected override Result GetTotalSpaceSizeImpl(out long totalSpace, string path)
{ {
totalSpace = new DriveInfo(BasePath).TotalSize; totalSpace = new DriveInfo(BasePath).TotalSize;
return Result.Success; return Result.Success;
} }
public Result Commit() protected override Result CommitImpl()
{ {
return Result.Success; return Result.Success;
} }
public Result QueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, string path) protected override Result QueryEntryImpl(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, string path)
{ {
return ResultFs.UnsupportedOperation.Log(); return ResultFs.UnsupportedOperation.Log();
} }

View file

@ -302,5 +302,16 @@ namespace LibHac.FsSystem.Save
return journalValidity; return journalValidity;
} }
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (!LeaveOpen)
{
BaseStorage?.Dispose();
}
}
}
} }
} }