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
// 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
private int _disposedState;
private bool IsDisposed => _disposedState != 0;
protected bool IsDisposed => _disposedState != 0;
protected abstract Result CreateDirectoryImpl(string path);
protected abstract Result CreateFileImpl(string path, long size, CreateFileOptions options);

View file

@ -115,6 +115,16 @@ namespace LibHac.Fs
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)
{
return handle.File.Parent.IsAccessLogEnabled;

View file

@ -6,7 +6,7 @@ namespace LibHac.Fs
/// <summary>
/// Provides an interface for accessing a file system. <c>/</c> is used as the path delimiter.
/// </summary>
public interface IFileSystem
public interface IFileSystem : IDisposable
{
/// <summary>
/// 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);
if (rc.IsFailure()) return rc;
var saveDataStorage = new FileStorage(saveDataFile);
fileSystem = new SaveDataFileSystem(Keyset, saveDataStorage, IntegrityCheckLevel.ErrorOnInvalid, true);
var saveDataStorage = new DisposingFileStorage(saveDataFile);
fileSystem = new SaveDataFileSystem(Keyset, saveDataStorage, IntegrityCheckLevel.ErrorOnInvalid, false);
// Todo: ISaveDataExtraDataAccessor

View file

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

View file

@ -6,12 +6,12 @@ namespace LibHac.FsService
{
public class FileSystemServer
{
internal const ulong SaveDataIndexerSaveId = 0x8000000000000000;
internal const ulong SaveIndexerId = 0x8000000000000000;
private FileSystemProxyCore FsProxyCore { get; }
/// <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; }
internal SaveDataIndexerManager SaveDataIndexerManager { get; }
@ -35,7 +35,7 @@ namespace LibHac.FsService
FsClient = new FileSystemClient(this, timer);
Timer = timer;
SaveDataIndexerManager = new SaveDataIndexerManager(FsClient, SaveDataIndexerSaveId);
SaveDataIndexerManager = new SaveDataIndexerManager(FsClient, SaveIndexerId);
}
/// <summary>

View file

@ -5,7 +5,7 @@ namespace LibHac.FsSystem
{
public class FileStorage : StorageBase
{
private IFile BaseFile { get; }
protected IFile BaseFile { get; }
public FileStorage(IFile baseFile)
{
@ -37,4 +37,17 @@ namespace LibHac.FsSystem
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
{
public class LocalFileSystem : IAttributeFileSystem
public class LocalFileSystem : AttributeFileSystemBase
{
private string BasePath { get; }
@ -30,7 +30,7 @@ namespace LibHac.FsSystem
return PathTools.Combine(BasePath, path);
}
public Result GetFileAttributes(string path, out NxFileAttributes attributes)
protected override Result GetFileAttributesImpl(string path, out NxFileAttributes attributes)
{
attributes = default;
@ -49,7 +49,7 @@ namespace LibHac.FsSystem
return Result.Success;
}
public Result SetFileAttributes(string path, NxFileAttributes attributes)
protected override Result SetFileAttributesImpl(string path, NxFileAttributes attributes)
{
string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -76,7 +76,7 @@ namespace LibHac.FsSystem
return Result.Success;
}
public Result GetFileSize(out long fileSize, string path)
protected override Result GetFileSizeImpl(out long fileSize, string path)
{
fileSize = default;
string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -87,12 +87,12 @@ namespace LibHac.FsSystem
return GetSizeInternal(out fileSize, info);
}
public Result CreateDirectory(string path)
protected override Result CreateDirectoryImpl(string path)
{
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));
@ -112,7 +112,7 @@ namespace LibHac.FsSystem
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));
@ -139,7 +139,7 @@ namespace LibHac.FsSystem
}
}
public Result DeleteDirectory(string path)
protected override Result DeleteDirectoryImpl(string path)
{
string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -149,7 +149,7 @@ namespace LibHac.FsSystem
return DeleteDirectoryInternal(dir, false);
}
public Result DeleteDirectoryRecursively(string path)
protected override Result DeleteDirectoryRecursivelyImpl(string path)
{
string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -159,7 +159,7 @@ namespace LibHac.FsSystem
return DeleteDirectoryInternal(dir, true);
}
public Result CleanDirectoryRecursively(string path)
protected override Result CleanDirectoryRecursivelyImpl(string path)
{
string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -184,7 +184,7 @@ namespace LibHac.FsSystem
return Result.Success;
}
public Result DeleteFile(string path)
protected override Result DeleteFileImpl(string path)
{
string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -194,7 +194,7 @@ namespace LibHac.FsSystem
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;
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;
string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -240,7 +240,7 @@ namespace LibHac.FsSystem
return Result.Success;
}
public Result RenameDirectory(string oldPath, string newPath)
protected override Result RenameDirectoryImpl(string oldPath, string newPath)
{
oldPath = PathTools.Normalize(oldPath);
newPath = PathTools.Normalize(newPath);
@ -263,7 +263,7 @@ namespace LibHac.FsSystem
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 dstLocalPath = ResolveLocalPath(PathTools.Normalize(newPath));
@ -280,7 +280,7 @@ namespace LibHac.FsSystem
return RenameFileInternal(srcFile, dstFile);
}
public Result GetEntryType(out DirectoryEntryType entryType, string path)
protected override Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path)
{
entryType = default;
string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -307,7 +307,7 @@ namespace LibHac.FsSystem
return ResultFs.PathNotFound.Log();
}
public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path)
protected override Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path)
{
timeStamp = default;
string localPath = ResolveLocalPath(PathTools.Normalize(path));
@ -324,24 +324,24 @@ namespace LibHac.FsSystem
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;
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;
return Result.Success;
}
public Result Commit()
protected override Result CommitImpl()
{
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();
}

View file

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