mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Ensure more FS classes are updated for 13.1.0
- FsSystem.ForwardingDirectory - FsSystem.ForwardingFile - FsSystem.ForwardingFileSystem - FsSystem.StorageLayoutTypeSetDirectory - FsSystem.StorageLayoutTypeSetFile - FsSystem.StorageLayoutTypeSetFileSystem - FsSystem.StorageLayoutTypeSetStorage - Fs.MemoryStorage - Fs.ReadOnlyFile - Fs.ReadOnlyFileSystem
This commit is contained in:
parent
a7ffae3a14
commit
2c2fed445f
6 changed files with 299 additions and 162 deletions
|
@ -1,14 +1,20 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LibHac.Fs;
|
||||
|
||||
/// <summary>
|
||||
/// Allows interacting with a <see cref="byte"/> array via the <see cref="IStorage"/> interface.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class MemoryStorage : IStorage
|
||||
{
|
||||
private byte[] StorageBuffer { get; }
|
||||
private byte[] _storageBuffer;
|
||||
|
||||
public MemoryStorage(byte[] buffer)
|
||||
{
|
||||
StorageBuffer = buffer;
|
||||
_storageBuffer = buffer;
|
||||
}
|
||||
|
||||
public override Result Read(long offset, Span<byte> destination)
|
||||
|
@ -16,10 +22,10 @@ public class MemoryStorage : IStorage
|
|||
if (destination.Length == 0)
|
||||
return Result.Success;
|
||||
|
||||
if (!CheckAccessRange(offset, destination.Length, StorageBuffer.Length))
|
||||
if (!CheckAccessRange(offset, destination.Length, _storageBuffer.Length))
|
||||
return ResultFs.OutOfRange.Log();
|
||||
|
||||
StorageBuffer.AsSpan((int)offset, destination.Length).CopyTo(destination);
|
||||
_storageBuffer.AsSpan((int)offset, destination.Length).CopyTo(destination);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
@ -29,10 +35,10 @@ public class MemoryStorage : IStorage
|
|||
if (source.Length == 0)
|
||||
return Result.Success;
|
||||
|
||||
if (!CheckAccessRange(offset, source.Length, StorageBuffer.Length))
|
||||
if (!CheckAccessRange(offset, source.Length, _storageBuffer.Length))
|
||||
return ResultFs.OutOfRange.Log();
|
||||
|
||||
source.CopyTo(StorageBuffer.AsSpan((int)offset));
|
||||
source.CopyTo(_storageBuffer.AsSpan((int)offset));
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
@ -49,7 +55,7 @@ public class MemoryStorage : IStorage
|
|||
|
||||
public override Result GetSize(out long size)
|
||||
{
|
||||
size = StorageBuffer.Length;
|
||||
size = _storageBuffer.Length;
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
@ -57,6 +63,18 @@ public class MemoryStorage : IStorage
|
|||
public override Result OperateRange(Span<byte> outBuffer, OperationId operationId, long offset, long size,
|
||||
ReadOnlySpan<byte> inBuffer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
switch (operationId)
|
||||
{
|
||||
case OperationId.InvalidateCache:
|
||||
return Result.Success;
|
||||
case OperationId.QueryRange:
|
||||
if (outBuffer.Length != Unsafe.SizeOf<QueryRangeInfo>())
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
Unsafe.As<byte, QueryRangeInfo>(ref MemoryMarshal.GetReference(outBuffer)).Clear();
|
||||
return Result.Success;
|
||||
default:
|
||||
return ResultFs.UnsupportedOperateRangeForMemoryStorage.Log();
|
||||
}
|
||||
}
|
||||
}
|
159
src/LibHac/Fs/ReadOnlyFileSystem.cs
Normal file
159
src/LibHac/Fs/ReadOnlyFileSystem.cs
Normal file
|
@ -0,0 +1,159 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Fs.Fsa;
|
||||
|
||||
namespace LibHac.Fs;
|
||||
|
||||
/// <summary>
|
||||
/// Wraps an <see cref="IFile"/> and only allows read operations on it.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
internal class ReadOnlyFile : IFile
|
||||
{
|
||||
private UniqueRef<IFile> _baseFile;
|
||||
|
||||
public ReadOnlyFile(ref UniqueRef<IFile> baseFile)
|
||||
{
|
||||
_baseFile = new UniqueRef<IFile>(ref baseFile);
|
||||
|
||||
Assert.SdkRequires(_baseFile.HasValue);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
_baseFile.Destroy();
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
protected override Result DoRead(out long bytesRead, long offset, Span<byte> destination,
|
||||
in ReadOption option)
|
||||
{
|
||||
return _baseFile.Get.Read(out bytesRead, offset, destination, option);
|
||||
}
|
||||
|
||||
protected override Result DoGetSize(out long size)
|
||||
{
|
||||
return _baseFile.Get.GetSize(out size);
|
||||
}
|
||||
|
||||
protected override Result DoFlush()
|
||||
{
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result DoWrite(long offset, ReadOnlySpan<byte> source, in WriteOption option)
|
||||
{
|
||||
return ResultFs.UnsupportedWriteForReadOnlyFile.Log();
|
||||
}
|
||||
|
||||
protected override Result DoSetSize(long size)
|
||||
{
|
||||
return ResultFs.UnsupportedWriteForReadOnlyFile.Log();
|
||||
}
|
||||
|
||||
protected override Result DoOperateRange(Span<byte> outBuffer, OperationId operationId, long offset, long size,
|
||||
ReadOnlySpan<byte> inBuffer)
|
||||
{
|
||||
switch (operationId)
|
||||
{
|
||||
case OperationId.InvalidateCache:
|
||||
case OperationId.QueryRange:
|
||||
return _baseFile.Get.OperateRange(outBuffer, operationId, offset, size, inBuffer);
|
||||
default:
|
||||
return ResultFs.UnsupportedOperateRangeForReadOnlyFile.Log();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps an <see cref="IFileSystem"/> and only allows read operations on it.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class ReadOnlyFileSystem : IFileSystem
|
||||
{
|
||||
private SharedRef<IFileSystem> _baseFileSystem;
|
||||
|
||||
public ReadOnlyFileSystem(ref SharedRef<IFileSystem> baseFileSystem)
|
||||
{
|
||||
_baseFileSystem = SharedRef<IFileSystem>.CreateMove(ref baseFileSystem);
|
||||
|
||||
Assert.SdkRequires(_baseFileSystem.HasValue);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
_baseFileSystem.Destroy();
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
protected override Result DoOpenFile(ref UniqueRef<IFile> outFile, in Path path, OpenMode mode)
|
||||
{
|
||||
// The Read flag must be the only flag set
|
||||
if ((mode & OpenMode.All) != OpenMode.Read)
|
||||
return ResultFs.InvalidModeForFileOpen.Log();
|
||||
|
||||
using var baseFile = new UniqueRef<IFile>();
|
||||
Result rc = _baseFileSystem.Get.OpenFile(ref baseFile.Ref(), in path, mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
outFile.Reset(new ReadOnlyFile(ref baseFile.Ref()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result DoOpenDirectory(ref UniqueRef<IDirectory> outDirectory, in Path path,
|
||||
OpenDirectoryMode mode)
|
||||
{
|
||||
// An IDirectory is already read-only so we don't need a wrapper ReadOnlyDictionary class
|
||||
return _baseFileSystem.Get.OpenDirectory(ref outDirectory, in path, mode);
|
||||
}
|
||||
|
||||
protected override Result DoGetEntryType(out DirectoryEntryType entryType, in Path path)
|
||||
{
|
||||
return _baseFileSystem.Get.GetEntryType(out entryType, in path);
|
||||
}
|
||||
|
||||
protected override Result DoCreateFile(in Path path, long size, CreateFileOptions option) =>
|
||||
ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoDeleteFile(in Path path) =>
|
||||
ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoCreateDirectory(in Path path) =>
|
||||
ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoDeleteDirectory(in Path path) =>
|
||||
ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoDeleteDirectoryRecursively(in Path path) =>
|
||||
ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoCleanDirectoryRecursively(in Path path) =>
|
||||
ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoRenameFile(in Path currentPath, in Path newPath) =>
|
||||
ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoRenameDirectory(in Path currentPath, in Path newPath) =>
|
||||
ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoCommit() =>
|
||||
Result.Success;
|
||||
|
||||
protected override Result DoCommitProvisionally(long counter) =>
|
||||
ResultFs.UnsupportedCommitProvisionallyForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoGetFreeSpaceSize(out long freeSpace, in Path path)
|
||||
{
|
||||
return _baseFileSystem.Get.GetFreeSpaceSize(out freeSpace, in path);
|
||||
}
|
||||
|
||||
protected override Result DoGetTotalSpaceSize(out long totalSpace, in Path path)
|
||||
{
|
||||
Unsafe.SkipInit(out totalSpace);
|
||||
return ResultFs.UnsupportedGetTotalSpaceSizeForReadOnlyFileSystem.Log();
|
||||
}
|
||||
}
|
|
@ -5,11 +5,80 @@ using LibHac.Fs.Fsa;
|
|||
|
||||
namespace LibHac.FsSystem;
|
||||
|
||||
/// <summary>
|
||||
/// An <see cref="IFile"/> wrapper that forwards all calls to the base <see cref="IFile"/>.
|
||||
/// Meant for use as a base class when the derived class only needs to override some of the methods.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class ForwardingFile : IFile
|
||||
{
|
||||
protected UniqueRef<IFile> BaseFile;
|
||||
|
||||
protected ForwardingFile(ref UniqueRef<IFile> baseFile)
|
||||
{
|
||||
BaseFile = new UniqueRef<IFile>(ref baseFile);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
BaseFile.Destroy();
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
protected override Result DoRead(out long bytesRead, long offset, Span<byte> destination, in ReadOption option) =>
|
||||
BaseFile.Get.Read(out bytesRead, offset, destination, in option);
|
||||
|
||||
protected override Result DoWrite(long offset, ReadOnlySpan<byte> source, in WriteOption option) =>
|
||||
BaseFile.Get.Write(offset, source, in option);
|
||||
|
||||
protected override Result DoFlush() => BaseFile.Get.Flush();
|
||||
|
||||
protected override Result DoSetSize(long size) => BaseFile.Get.SetSize(size);
|
||||
|
||||
protected override Result DoGetSize(out long size) => BaseFile.Get.GetSize(out size);
|
||||
|
||||
protected override Result DoOperateRange(Span<byte> outBuffer, OperationId operationId, long offset, long size,
|
||||
ReadOnlySpan<byte> inBuffer) => BaseFile.Get.OperateRange(outBuffer, operationId, offset, size, inBuffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An <see cref="IDirectory"/> wrapper that forwards all calls to the base <see cref="IDirectory"/>.
|
||||
/// Primarily meant for use as a base class when the derived class only needs to override some of the methods.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class ForwardingDirectory : IDirectory
|
||||
{
|
||||
protected UniqueRef<IDirectory> BaseDirectory;
|
||||
|
||||
protected ForwardingDirectory(ref UniqueRef<IDirectory> baseDirectory)
|
||||
{
|
||||
BaseDirectory = new UniqueRef<IDirectory>(ref baseDirectory);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
BaseDirectory.Destroy();
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
protected override Result DoRead(out long entriesRead, Span<DirectoryEntry> entryBuffer) =>
|
||||
BaseDirectory.Get.Read(out entriesRead, entryBuffer);
|
||||
|
||||
protected override Result DoGetEntryCount(out long entryCount) => BaseDirectory.Get.GetEntryCount(out entryCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An <see cref="IFileSystem"/> wrapper that forwards all calls to the base <see cref="IFileSystem"/>.
|
||||
/// Primarily meant for use as a base class when the derived class only needs to override some of the methods.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class ForwardingFileSystem : IFileSystem
|
||||
{
|
||||
protected SharedRef<IFileSystem> BaseFileSystem;
|
||||
|
||||
public ForwardingFileSystem(ref SharedRef<IFileSystem> baseFileSystem)
|
||||
protected ForwardingFileSystem(ref SharedRef<IFileSystem> baseFileSystem)
|
||||
{
|
||||
BaseFileSystem = SharedRef<IFileSystem>.CreateMove(ref baseFileSystem);
|
||||
}
|
||||
|
@ -17,6 +86,7 @@ public class ForwardingFileSystem : IFileSystem
|
|||
public override void Dispose()
|
||||
{
|
||||
BaseFileSystem.Destroy();
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
|
@ -71,4 +141,4 @@ public class ForwardingFileSystem : IFileSystem
|
|||
|
||||
protected override Result DoQueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId,
|
||||
in Path path) => BaseFileSystem.Get.QueryEntry(outBuffer, inBuffer, queryId, in path);
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
|
||||
namespace LibHac.FsSystem;
|
||||
|
||||
public class ReadOnlyFile : IFile
|
||||
{
|
||||
private UniqueRef<IFile> _baseFile;
|
||||
|
||||
public ReadOnlyFile(ref UniqueRef<IFile> baseFile)
|
||||
{
|
||||
_baseFile = new UniqueRef<IFile>(ref baseFile);
|
||||
}
|
||||
|
||||
protected override Result DoRead(out long bytesRead, long offset, Span<byte> destination,
|
||||
in ReadOption option)
|
||||
{
|
||||
return _baseFile.Get.Read(out bytesRead, offset, destination, option);
|
||||
}
|
||||
|
||||
protected override Result DoGetSize(out long size)
|
||||
{
|
||||
return _baseFile.Get.GetSize(out size);
|
||||
}
|
||||
|
||||
protected override Result DoFlush()
|
||||
{
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result DoWrite(long offset, ReadOnlySpan<byte> source, in WriteOption option)
|
||||
{
|
||||
return ResultFs.WriteUnpermitted.Log();
|
||||
}
|
||||
|
||||
protected override Result DoSetSize(long size)
|
||||
{
|
||||
return ResultFs.WriteUnpermitted.Log();
|
||||
}
|
||||
|
||||
protected override Result DoOperateRange(Span<byte> outBuffer, OperationId operationId, long offset, long size, ReadOnlySpan<byte> inBuffer)
|
||||
{
|
||||
switch (operationId)
|
||||
{
|
||||
case OperationId.InvalidateCache:
|
||||
case OperationId.QueryRange:
|
||||
return _baseFile.Get.OperateRange(outBuffer, operationId, offset, size, inBuffer);
|
||||
default:
|
||||
return ResultFs.UnsupportedOperateRangeForReadOnlyFile.Log();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
using LibHac.Common;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
|
||||
namespace LibHac.FsSystem;
|
||||
|
||||
public class ReadOnlyFileSystem : IFileSystem
|
||||
{
|
||||
private SharedRef<IFileSystem> _baseFileSystem;
|
||||
|
||||
public ReadOnlyFileSystem(ref SharedRef<IFileSystem> baseFileSystem)
|
||||
{
|
||||
_baseFileSystem = SharedRef<IFileSystem>.CreateMove(ref baseFileSystem);
|
||||
|
||||
Assert.SdkRequires(_baseFileSystem.HasValue);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
_baseFileSystem.Destroy();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
protected override Result DoOpenDirectory(ref UniqueRef<IDirectory> outDirectory, in Path path,
|
||||
OpenDirectoryMode mode)
|
||||
{
|
||||
return _baseFileSystem.Get.OpenDirectory(ref outDirectory, in path, mode);
|
||||
}
|
||||
|
||||
protected override Result DoOpenFile(ref UniqueRef<IFile> outFile, in Path path, OpenMode mode)
|
||||
{
|
||||
using var baseFile = new UniqueRef<IFile>();
|
||||
Result rc = _baseFileSystem.Get.OpenFile(ref baseFile.Ref(), in path, mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
outFile.Reset(new ReadOnlyFile(ref baseFile.Ref()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result DoGetEntryType(out DirectoryEntryType entryType, in Path path)
|
||||
{
|
||||
return _baseFileSystem.Get.GetEntryType(out entryType, in path);
|
||||
}
|
||||
|
||||
protected override Result DoGetFreeSpaceSize(out long freeSpace, in Path path)
|
||||
{
|
||||
return _baseFileSystem.Get.GetFreeSpaceSize(out freeSpace, in path);
|
||||
}
|
||||
|
||||
protected override Result DoGetTotalSpaceSize(out long totalSpace, in Path path)
|
||||
{
|
||||
return _baseFileSystem.Get.GetTotalSpaceSize(out totalSpace, in path);
|
||||
|
||||
// FS does:
|
||||
// return ResultFs.UnsupportedOperationReadOnlyFileSystemGetSpace.Log();
|
||||
}
|
||||
|
||||
protected override Result DoGetFileTimeStampRaw(out FileTimeStampRaw timeStamp, in Path path)
|
||||
{
|
||||
return _baseFileSystem.Get.GetFileTimeStampRaw(out timeStamp, in path);
|
||||
|
||||
// FS does:
|
||||
// return ResultFs.NotImplemented.Log();
|
||||
}
|
||||
|
||||
protected override Result DoCommit()
|
||||
{
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override Result DoCreateDirectory(in Path path) => ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoCreateFile(in Path path, long size, CreateFileOptions option) => ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoDeleteDirectory(in Path path) => ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoDeleteDirectoryRecursively(in Path path) => ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoCleanDirectoryRecursively(in Path path) => ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoDeleteFile(in Path path) => ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoRenameDirectory(in Path currentPath, in Path newPath) => ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
|
||||
protected override Result DoRenameFile(in Path currentPath, in Path newPath) => ResultFs.UnsupportedWriteForReadOnlyFileSystem.Log();
|
||||
}
|
|
@ -18,6 +18,10 @@ internal enum StorageType
|
|||
All = Bis | SdCard | GameCard | Usb
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains functions for validating the storage layout type flag.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
internal static class StorageLayoutType
|
||||
{
|
||||
public static bool IsStorageFlagValid(StorageType storageFlag)
|
||||
|
@ -40,6 +44,11 @@ internal struct ScopedStorageLayoutTypeSetter : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps an <see cref="IStorage"/>, automatically setting the thread's storage type when accessing the storage.
|
||||
/// This is used to determine which storage speed emulation parameters to use for the current thread.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
internal class StorageLayoutTypeSetStorage : IStorage
|
||||
{
|
||||
private SharedRef<IStorage> _baseStorage;
|
||||
|
@ -55,8 +64,10 @@ internal class StorageLayoutTypeSetStorage : IStorage
|
|||
|
||||
public override void Dispose()
|
||||
{
|
||||
using var scopedContext = new ScopedStorageLayoutTypeSetter(_storageFlag);
|
||||
_baseStorage.Destroy();
|
||||
using (new ScopedStorageLayoutTypeSetter(_storageFlag))
|
||||
{
|
||||
_baseStorage.Destroy();
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
@ -99,6 +110,11 @@ internal class StorageLayoutTypeSetStorage : IStorage
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps an <see cref="IFile"/>, automatically setting the thread's storage type when accessing the file.
|
||||
/// This is used to determine which storage speed emulation parameters to use for the current thread.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
internal class StorageLayoutTypeSetFile : IFile
|
||||
{
|
||||
private IFile _baseFile;
|
||||
|
@ -126,11 +142,12 @@ internal class StorageLayoutTypeSetFile : IFile
|
|||
|
||||
public override void Dispose()
|
||||
{
|
||||
using var scopedContext = new ScopedStorageLayoutTypeSetter(_storageFlag);
|
||||
|
||||
_baseFile = null;
|
||||
_baseFileUnique.Destroy();
|
||||
_baseFileShared.Destroy();
|
||||
using (new ScopedStorageLayoutTypeSetter(_storageFlag))
|
||||
{
|
||||
_baseFile = null;
|
||||
_baseFileUnique.Destroy();
|
||||
_baseFileShared.Destroy();
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
@ -173,6 +190,11 @@ internal class StorageLayoutTypeSetFile : IFile
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps an <see cref="IDirectory"/>, automatically setting the thread's storage type when accessing the directory.
|
||||
/// This is used to determine which storage speed emulation parameters to use for the current thread.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
internal class StorageLayoutTypeSetDirectory : IDirectory
|
||||
{
|
||||
private UniqueRef<IDirectory> _baseDirectory;
|
||||
|
@ -186,8 +208,10 @@ internal class StorageLayoutTypeSetDirectory : IDirectory
|
|||
|
||||
public override void Dispose()
|
||||
{
|
||||
using var scopedContext = new ScopedStorageLayoutTypeSetter(_storageFlag);
|
||||
_baseDirectory.Destroy();
|
||||
using (new ScopedStorageLayoutTypeSetter(_storageFlag))
|
||||
{
|
||||
_baseDirectory.Destroy();
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
@ -205,6 +229,10 @@ internal class StorageLayoutTypeSetDirectory : IDirectory
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps an <see cref="IFileSystem"/>, automatically setting the thread's storage type when accessing the file system.
|
||||
/// This is used to determine which storage speed emulation parameters to use for the current thread.
|
||||
/// </summary>
|
||||
internal class StorageLayoutTypeSetFileSystem : IFileSystem
|
||||
{
|
||||
private SharedRef<IFileSystem> _baseFileSystem;
|
||||
|
@ -220,8 +248,11 @@ internal class StorageLayoutTypeSetFileSystem : IFileSystem
|
|||
|
||||
public override void Dispose()
|
||||
{
|
||||
using var scopedContext = new ScopedStorageLayoutTypeSetter(_storageFlag);
|
||||
_baseFileSystem.Destroy();
|
||||
using (new ScopedStorageLayoutTypeSetter(_storageFlag))
|
||||
{
|
||||
_baseFileSystem.Destroy();
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue