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;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace LibHac.Fs;
|
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
|
public class MemoryStorage : IStorage
|
||||||
{
|
{
|
||||||
private byte[] StorageBuffer { get; }
|
private byte[] _storageBuffer;
|
||||||
|
|
||||||
public MemoryStorage(byte[] buffer)
|
public MemoryStorage(byte[] buffer)
|
||||||
{
|
{
|
||||||
StorageBuffer = buffer;
|
_storageBuffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result Read(long offset, Span<byte> destination)
|
public override Result Read(long offset, Span<byte> destination)
|
||||||
|
@ -16,10 +22,10 @@ public class MemoryStorage : IStorage
|
||||||
if (destination.Length == 0)
|
if (destination.Length == 0)
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
|
||||||
if (!CheckAccessRange(offset, destination.Length, StorageBuffer.Length))
|
if (!CheckAccessRange(offset, destination.Length, _storageBuffer.Length))
|
||||||
return ResultFs.OutOfRange.Log();
|
return ResultFs.OutOfRange.Log();
|
||||||
|
|
||||||
StorageBuffer.AsSpan((int)offset, destination.Length).CopyTo(destination);
|
_storageBuffer.AsSpan((int)offset, destination.Length).CopyTo(destination);
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
@ -29,10 +35,10 @@ public class MemoryStorage : IStorage
|
||||||
if (source.Length == 0)
|
if (source.Length == 0)
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
|
||||||
if (!CheckAccessRange(offset, source.Length, StorageBuffer.Length))
|
if (!CheckAccessRange(offset, source.Length, _storageBuffer.Length))
|
||||||
return ResultFs.OutOfRange.Log();
|
return ResultFs.OutOfRange.Log();
|
||||||
|
|
||||||
source.CopyTo(StorageBuffer.AsSpan((int)offset));
|
source.CopyTo(_storageBuffer.AsSpan((int)offset));
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +55,7 @@ public class MemoryStorage : IStorage
|
||||||
|
|
||||||
public override Result GetSize(out long size)
|
public override Result GetSize(out long size)
|
||||||
{
|
{
|
||||||
size = StorageBuffer.Length;
|
size = _storageBuffer.Length;
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
@ -57,6 +63,18 @@ public class MemoryStorage : IStorage
|
||||||
public override Result OperateRange(Span<byte> outBuffer, OperationId operationId, long offset, long size,
|
public override Result OperateRange(Span<byte> outBuffer, OperationId operationId, long offset, long size,
|
||||||
ReadOnlySpan<byte> inBuffer)
|
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;
|
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
|
public class ForwardingFileSystem : IFileSystem
|
||||||
{
|
{
|
||||||
protected SharedRef<IFileSystem> BaseFileSystem;
|
protected SharedRef<IFileSystem> BaseFileSystem;
|
||||||
|
|
||||||
public ForwardingFileSystem(ref SharedRef<IFileSystem> baseFileSystem)
|
protected ForwardingFileSystem(ref SharedRef<IFileSystem> baseFileSystem)
|
||||||
{
|
{
|
||||||
BaseFileSystem = SharedRef<IFileSystem>.CreateMove(ref baseFileSystem);
|
BaseFileSystem = SharedRef<IFileSystem>.CreateMove(ref baseFileSystem);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +86,7 @@ public class ForwardingFileSystem : IFileSystem
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
BaseFileSystem.Destroy();
|
BaseFileSystem.Destroy();
|
||||||
|
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
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
|
internal static class StorageLayoutType
|
||||||
{
|
{
|
||||||
public static bool IsStorageFlagValid(StorageType storageFlag)
|
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
|
internal class StorageLayoutTypeSetStorage : IStorage
|
||||||
{
|
{
|
||||||
private SharedRef<IStorage> _baseStorage;
|
private SharedRef<IStorage> _baseStorage;
|
||||||
|
@ -55,8 +64,10 @@ internal class StorageLayoutTypeSetStorage : IStorage
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
using var scopedContext = new ScopedStorageLayoutTypeSetter(_storageFlag);
|
using (new ScopedStorageLayoutTypeSetter(_storageFlag))
|
||||||
|
{
|
||||||
_baseStorage.Destroy();
|
_baseStorage.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
base.Dispose();
|
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
|
internal class StorageLayoutTypeSetFile : IFile
|
||||||
{
|
{
|
||||||
private IFile _baseFile;
|
private IFile _baseFile;
|
||||||
|
@ -126,11 +142,12 @@ internal class StorageLayoutTypeSetFile : IFile
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
using var scopedContext = new ScopedStorageLayoutTypeSetter(_storageFlag);
|
using (new ScopedStorageLayoutTypeSetter(_storageFlag))
|
||||||
|
{
|
||||||
_baseFile = null;
|
_baseFile = null;
|
||||||
_baseFileUnique.Destroy();
|
_baseFileUnique.Destroy();
|
||||||
_baseFileShared.Destroy();
|
_baseFileShared.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
base.Dispose();
|
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
|
internal class StorageLayoutTypeSetDirectory : IDirectory
|
||||||
{
|
{
|
||||||
private UniqueRef<IDirectory> _baseDirectory;
|
private UniqueRef<IDirectory> _baseDirectory;
|
||||||
|
@ -186,8 +208,10 @@ internal class StorageLayoutTypeSetDirectory : IDirectory
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
using var scopedContext = new ScopedStorageLayoutTypeSetter(_storageFlag);
|
using (new ScopedStorageLayoutTypeSetter(_storageFlag))
|
||||||
|
{
|
||||||
_baseDirectory.Destroy();
|
_baseDirectory.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
base.Dispose();
|
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
|
internal class StorageLayoutTypeSetFileSystem : IFileSystem
|
||||||
{
|
{
|
||||||
private SharedRef<IFileSystem> _baseFileSystem;
|
private SharedRef<IFileSystem> _baseFileSystem;
|
||||||
|
@ -220,8 +248,11 @@ internal class StorageLayoutTypeSetFileSystem : IFileSystem
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
using var scopedContext = new ScopedStorageLayoutTypeSetter(_storageFlag);
|
using (new ScopedStorageLayoutTypeSetter(_storageFlag))
|
||||||
|
{
|
||||||
_baseFileSystem.Destroy();
|
_baseFileSystem.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue