mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Implement SaveDataFileSystem
This commit is contained in:
parent
2b2b7471ea
commit
2c14770ceb
6 changed files with 181 additions and 54 deletions
|
@ -1068,6 +1068,7 @@ Module,DescriptionStart,DescriptionEnd,Flags,Namespace,Name,Summary
|
||||||
2,6395,,,,UnsupportedRollbackOnlyModifiedForApplicationTemporaryFileSystem,
|
2,6395,,,,UnsupportedRollbackOnlyModifiedForApplicationTemporaryFileSystem,
|
||||||
2,6396,,,,UnsupportedRollbackOnlyModifiedForDirectorySaveDataFileSystem,
|
2,6396,,,,UnsupportedRollbackOnlyModifiedForDirectorySaveDataFileSystem,
|
||||||
2,6397,,,,UnsupportedOperateRangeForRegionSwitchStorage,
|
2,6397,,,,UnsupportedOperateRangeForRegionSwitchStorage,
|
||||||
|
2,6398,,,,UnsupportedOperateRangeForSaveDataFile,
|
||||||
|
|
||||||
2,6400,6449,,,PermissionDenied,
|
2,6400,6449,,,PermissionDenied,
|
||||||
2,6403,,,,HostFileSystemOperationDisabled,Returned when opening a host FS on a retail device.
|
2,6403,,,,HostFileSystemOperationDisabled,Returned when opening a host FS on a retail device.
|
||||||
|
|
|
|
@ -1960,6 +1960,8 @@ public static class ResultFs
|
||||||
public static Result.Base UnsupportedRollbackOnlyModifiedForDirectorySaveDataFileSystem => new Result.Base(ModuleFs, 6396);
|
public static Result.Base UnsupportedRollbackOnlyModifiedForDirectorySaveDataFileSystem => new Result.Base(ModuleFs, 6396);
|
||||||
/// <summary>Error code: 2002-6397; Inner value: 0x31fa02</summary>
|
/// <summary>Error code: 2002-6397; Inner value: 0x31fa02</summary>
|
||||||
public static Result.Base UnsupportedOperateRangeForRegionSwitchStorage => new Result.Base(ModuleFs, 6397);
|
public static Result.Base UnsupportedOperateRangeForRegionSwitchStorage => new Result.Base(ModuleFs, 6397);
|
||||||
|
/// <summary>Error code: 2002-6398; Inner value: 0x31fc02</summary>
|
||||||
|
public static Result.Base UnsupportedOperateRangeForSaveDataFile => new Result.Base(ModuleFs, 6398);
|
||||||
|
|
||||||
/// <summary>Error code: 2002-6400; Range: 6400-6449; Inner value: 0x320002</summary>
|
/// <summary>Error code: 2002-6400; Range: 6400-6449; Inner value: 0x320002</summary>
|
||||||
public static Result.Base PermissionDenied { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleFs, 6400, 6449); }
|
public static Result.Base PermissionDenied { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleFs, 6400, 6449); }
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace LibHac.FsSystem;
|
||||||
/// Wraps an <see cref="IFile"/>, converting its returned <see cref="Result"/>s to different
|
/// Wraps an <see cref="IFile"/>, converting its returned <see cref="Result"/>s to different
|
||||||
/// <see cref="Result"/>s based on the <see cref="ConvertResult"/> function.
|
/// <see cref="Result"/>s based on the <see cref="ConvertResult"/> function.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>Based on nnSdk 14.3.0 (FS 14.1.0)</remarks>
|
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||||
public abstract class IResultConvertFile : IFile
|
public abstract class IResultConvertFile : IFile
|
||||||
{
|
{
|
||||||
private UniqueRef<IFile> _baseFile;
|
private UniqueRef<IFile> _baseFile;
|
||||||
|
@ -66,7 +66,7 @@ public abstract class IResultConvertFile : IFile
|
||||||
/// Wraps an <see cref="IDirectory"/>, converting its returned <see cref="Result"/>s to different
|
/// Wraps an <see cref="IDirectory"/>, converting its returned <see cref="Result"/>s to different
|
||||||
/// <see cref="Result"/>s based on the <see cref="ConvertResult"/> function.
|
/// <see cref="Result"/>s based on the <see cref="ConvertResult"/> function.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>Based on nnSdk 14.3.0 (FS 14.1.0)</remarks>
|
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||||
public abstract class IResultConvertDirectory : IDirectory
|
public abstract class IResultConvertDirectory : IDirectory
|
||||||
{
|
{
|
||||||
private UniqueRef<IDirectory> _baseDirectory;
|
private UniqueRef<IDirectory> _baseDirectory;
|
||||||
|
@ -101,7 +101,7 @@ public abstract class IResultConvertDirectory : IDirectory
|
||||||
/// Wraps an <see cref="IFileSystem"/>, converting its returned <see cref="Result"/>s to different
|
/// Wraps an <see cref="IFileSystem"/>, converting its returned <see cref="Result"/>s to different
|
||||||
/// <see cref="Result"/>s based on the <see cref="ConvertResult"/> function.
|
/// <see cref="Result"/>s based on the <see cref="ConvertResult"/> function.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>Based on nnSdk 14.3.0 (FS 14.1.0)</remarks>
|
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||||
public abstract class IResultConvertFileSystem<T> : ISaveDataFileSystem where T : IFileSystem
|
public abstract class IResultConvertFileSystem<T> : ISaveDataFileSystem where T : IFileSystem
|
||||||
{
|
{
|
||||||
private SharedRef<T> _baseFileSystem;
|
private SharedRef<T> _baseFileSystem;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// ReSharper disable UnusedMember.Local UnusedType.Local
|
using System;
|
||||||
#pragma warning disable CS0169 // Field is never used
|
using System.Runtime.CompilerServices;
|
||||||
using System;
|
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
|
using LibHac.Diag;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
using LibHac.FsSystem.Save;
|
using LibHac.FsSystem.Save;
|
||||||
|
@ -9,52 +9,92 @@ using LibHac.Os;
|
||||||
|
|
||||||
namespace LibHac.FsSystem;
|
namespace LibHac.FsSystem;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wraps an <see cref="IFile"/> opened by a <see cref="SaveDataFileSystem"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||||
file class SaveDataFile : IFile
|
file class SaveDataFile : IFile
|
||||||
{
|
{
|
||||||
private UniqueRef<IFile> _file;
|
private UniqueRef<IFile> _file;
|
||||||
|
|
||||||
public SaveDataFile(ref UniqueRef<IFile> file)
|
public SaveDataFile(ref UniqueRef<IFile> file)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_file = new UniqueRef<IFile>(ref file);
|
||||||
|
|
||||||
|
Assert.SdkRequiresNotNull(in _file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNull(in _file);
|
||||||
|
|
||||||
|
_file.Destroy();
|
||||||
|
base.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoRead(out long bytesRead, long offset, Span<byte> destination, in ReadOption option)
|
protected override Result DoRead(out long bytesRead, long offset, Span<byte> destination, in ReadOption option)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNull(in _file);
|
||||||
|
|
||||||
|
Result res = _file.Get.Read(out bytesRead, offset, destination);
|
||||||
|
|
||||||
|
if (res.IsFailure())
|
||||||
|
{
|
||||||
|
if (ResultFs.InvalidSaveDataFileReadOffset.Includes(res))
|
||||||
|
{
|
||||||
|
return ResultFs.OutOfRange.LogConverted(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.Miss();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoWrite(long offset, ReadOnlySpan<byte> source, in WriteOption option)
|
protected override Result DoWrite(long offset, ReadOnlySpan<byte> source, in WriteOption option)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNull(in _file);
|
||||||
|
|
||||||
|
return _file.Get.Write(offset, source, in option).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoFlush()
|
protected override Result DoFlush()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNull(in _file);
|
||||||
|
|
||||||
|
return _file.Get.Flush().Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoSetSize(long size)
|
protected override Result DoSetSize(long size)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNull(in _file);
|
||||||
|
|
||||||
|
return _file.Get.SetSize(size).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoGetSize(out long size)
|
protected override Result DoGetSize(out long size)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNull(in _file);
|
||||||
|
|
||||||
|
return _file.Get.GetSize(out size).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoOperateRange(Span<byte> outBuffer, OperationId operationId, long offset, long size,
|
protected override Result DoOperateRange(Span<byte> outBuffer, OperationId operationId, long offset, long size,
|
||||||
ReadOnlySpan<byte> inBuffer)
|
ReadOnlySpan<byte> inBuffer)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNull(in _file);
|
||||||
|
|
||||||
|
if (operationId == OperationId.InvalidateCache)
|
||||||
|
return ResultFs.UnsupportedOperateRangeForSaveDataFile.Log();
|
||||||
|
|
||||||
|
return _file.Get.OperateRange(outBuffer, operationId, offset, size, inBuffer).Ret();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads and writes to the file system inside a journal integrity save data image file.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||||
public class SaveDataFileSystem : ISaveDataFileSystem, InternalStorageFileSystemHolder
|
public class SaveDataFileSystem : ISaveDataFileSystem, InternalStorageFileSystemHolder
|
||||||
{
|
{
|
||||||
private SharedRef<IStorage> _baseStorage;
|
private SharedRef<IStorage> _baseStorage;
|
||||||
|
@ -69,39 +109,75 @@ public class SaveDataFileSystem : ISaveDataFileSystem, InternalStorageFileSystem
|
||||||
|
|
||||||
public SaveDataFileSystem()
|
public SaveDataFileSystem()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_baseStorage = new SharedRef<IStorage>();
|
||||||
|
_saveFsDriver = new JournalIntegritySaveDataFileSystemDriver();
|
||||||
|
_cacheObserver = null;
|
||||||
|
_mutex = new SdkMutex();
|
||||||
|
_canCommitProvisionally = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_saveFsDriver.FinalizeObject();
|
||||||
|
_cacheObserver?.Unregister(_spaceId, _saveDataId);
|
||||||
|
|
||||||
|
_saveFsDriver.Dispose();
|
||||||
|
_baseStorage.Destroy();
|
||||||
|
base.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result ExtractParameters(out JournalIntegritySaveDataParameters outParam, IStorage saveStorage,
|
public static Result ExtractParameters(out JournalIntegritySaveDataParameters outParam, IStorage saveStorage,
|
||||||
IBufferManager bufferManager, IMacGenerator macGenerator,
|
IBufferManager bufferManager, IMacGenerator macGenerator,
|
||||||
IHash256GeneratorFactorySelector hashGeneratorFactorySelector, uint minimumVersion)
|
IHash256GeneratorFactorySelector hashGeneratorFactorySelector, uint minimumVersion)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
UnsafeHelpers.SkipParamInit(out outParam);
|
||||||
|
|
||||||
|
using var fileSystem = new JournalIntegritySaveDataFileSystemDriver();
|
||||||
|
|
||||||
|
Result res = saveStorage.GetSize(out long size);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
using var saveSubStorage = new ValueSubStorage(saveStorage, 0, size);
|
||||||
|
res = fileSystem.Initialize(in saveSubStorage, bufferManager, macGenerator, hashGeneratorFactorySelector, minimumVersion);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
fileSystem.ExtractParameters(out outParam);
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result Initialize(IStorage baseStorage, IBufferManager bufferManager, IMacGenerator macGenerator,
|
public Result Initialize(IStorage baseStorage, IBufferManager bufferManager, IMacGenerator macGenerator,
|
||||||
IHash256GeneratorFactorySelector hashGeneratorFactorySelector, uint minimumVersion, bool canCommitProvisionally)
|
IHash256GeneratorFactorySelector hashGeneratorFactorySelector, uint minimumVersion, bool canCommitProvisionally)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Initialize(baseStorage, bufferManager, macGenerator, hashGeneratorFactorySelector, timeStampGetter: null,
|
||||||
|
randomGenerator: null, minimumVersion, canCommitProvisionally).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result Initialize(IStorage baseStorage, IBufferManager bufferManager, IMacGenerator macGenerator,
|
public Result Initialize(IStorage baseStorage, IBufferManager bufferManager, IMacGenerator macGenerator,
|
||||||
IHash256GeneratorFactorySelector hashGeneratorFactorySelector, ISaveDataCommitTimeStampGetter timeStampGetter,
|
IHash256GeneratorFactorySelector hashGeneratorFactorySelector, ISaveDataCommitTimeStampGetter timeStampGetter,
|
||||||
RandomDataGenerator randomGenerator, uint minimumVersion, bool canCommitProvisionally)
|
RandomDataGenerator randomGenerator, uint minimumVersion, bool canCommitProvisionally)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Result res = baseStorage.GetSize(out long size);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
using var baseSubStorage = new ValueSubStorage(baseStorage, 0, size);
|
||||||
|
res = _saveFsDriver.Initialize(in baseSubStorage, bufferManager, macGenerator, hashGeneratorFactorySelector, minimumVersion);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
_commitTimeStampGetter = timeStampGetter;
|
||||||
|
_randomGeneratorForCommit = randomGenerator;
|
||||||
|
_canCommitProvisionally = canCommitProvisionally;
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result Initialize(ref readonly SharedRef<IStorage> baseStorage, IBufferManager bufferManager,
|
public Result Initialize(ref readonly SharedRef<IStorage> baseStorage, IBufferManager bufferManager,
|
||||||
IMacGenerator macGenerator, IHash256GeneratorFactorySelector hashGeneratorFactorySelector, uint minimumVersion,
|
IMacGenerator macGenerator, IHash256GeneratorFactorySelector hashGeneratorFactorySelector, uint minimumVersion,
|
||||||
bool canCommitProvisionally)
|
bool canCommitProvisionally)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_baseStorage.SetByCopy(in baseStorage);
|
||||||
|
|
||||||
|
return Initialize(_baseStorage.Get, bufferManager, macGenerator, hashGeneratorFactorySelector, minimumVersion,
|
||||||
|
canCommitProvisionally).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result Initialize(ref readonly SharedRef<IStorage> baseStorage, IBufferManager bufferManager,
|
public Result Initialize(ref readonly SharedRef<IStorage> baseStorage, IBufferManager bufferManager,
|
||||||
|
@ -109,136 +185,184 @@ public class SaveDataFileSystem : ISaveDataFileSystem, InternalStorageFileSystem
|
||||||
ISaveDataCommitTimeStampGetter timeStampGetter, RandomDataGenerator randomGenerator, uint minimumVersion,
|
ISaveDataCommitTimeStampGetter timeStampGetter, RandomDataGenerator randomGenerator, uint minimumVersion,
|
||||||
bool canCommitProvisionally)
|
bool canCommitProvisionally)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_baseStorage.SetByCopy(in baseStorage);
|
||||||
|
|
||||||
|
return Initialize(_baseStorage.Get, bufferManager, macGenerator, hashGeneratorFactorySelector, timeStampGetter,
|
||||||
|
randomGenerator, minimumVersion, canCommitProvisionally).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoCreateFile(ref readonly Path path, long size, CreateFileOptions option)
|
protected override Result DoCreateFile(ref readonly Path path, long size, CreateFileOptions option)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.CreateFile(in path, size, option).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoDeleteFile(ref readonly Path path)
|
protected override Result DoDeleteFile(ref readonly Path path)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.DeleteFile(in path).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoCreateDirectory(ref readonly Path path)
|
protected override Result DoCreateDirectory(ref readonly Path path)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.CreateDirectory(in path).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoDeleteDirectory(ref readonly Path path)
|
protected override Result DoDeleteDirectory(ref readonly Path path)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.DeleteDirectory(in path).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoDeleteDirectoryRecursively(ref readonly Path path)
|
protected override Result DoDeleteDirectoryRecursively(ref readonly Path path)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.DeleteDirectoryRecursively(in path).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoCleanDirectoryRecursively(ref readonly Path path)
|
protected override Result DoCleanDirectoryRecursively(ref readonly Path path)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.CleanDirectoryRecursively(in path).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoRenameFile(ref readonly Path currentPath, ref readonly Path newPath)
|
protected override Result DoRenameFile(ref readonly Path currentPath, ref readonly Path newPath)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.RenameFile(in currentPath, in newPath).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoRenameDirectory(ref readonly Path currentPath, ref readonly Path newPath)
|
protected override Result DoRenameDirectory(ref readonly Path currentPath, ref readonly Path newPath)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.RenameDirectory(in currentPath, in newPath).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoGetEntryType(out DirectoryEntryType entryType, ref readonly Path path)
|
protected override Result DoGetEntryType(out DirectoryEntryType entryType, ref readonly Path path)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.GetEntryType(out entryType, in path).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoOpenFile(ref UniqueRef<IFile> outFile, ref readonly Path path, OpenMode mode)
|
protected override Result DoOpenFile(ref UniqueRef<IFile> outFile, ref readonly Path path, OpenMode mode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var file = new UniqueRef<IFile>();
|
||||||
|
Result res = _saveFsDriver.OpenFile(ref file.Ref, in path, mode);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
using var wrapperFile = new UniqueRef<SaveDataFile>(new SaveDataFile(ref file.Ref));
|
||||||
|
|
||||||
|
outFile.Set(ref wrapperFile.Ref);
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoOpenDirectory(ref UniqueRef<IDirectory> outDirectory, ref readonly Path path, OpenDirectoryMode mode)
|
protected override Result DoOpenDirectory(ref UniqueRef<IDirectory> outDirectory, ref readonly Path path, OpenDirectoryMode mode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.OpenDirectory(ref outDirectory, in path, mode).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result DoCommit(bool updateTimeStamp)
|
private Result DoCommit(bool updateTimeStamp)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (updateTimeStamp && _commitTimeStampGetter is not null)
|
||||||
|
{
|
||||||
|
Assert.SdkNotNull(_randomGeneratorForCommit);
|
||||||
|
|
||||||
|
Result res = ReadExtraData(out SaveDataExtraData extraData);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
res = _commitTimeStampGetter.Get(out long timeStamp);
|
||||||
|
if (res.IsSuccess())
|
||||||
|
extraData.TimeStamp = timeStamp;
|
||||||
|
|
||||||
|
long commitId = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
_randomGeneratorForCommit(SpanHelpers.AsByteSpan(ref commitId));
|
||||||
|
} while (commitId == 0 || commitId == extraData.CommitId);
|
||||||
|
|
||||||
|
extraData.CommitId = commitId;
|
||||||
|
|
||||||
|
res = WriteExtraData(in extraData);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _saveFsDriver.Commit().Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoCommit()
|
protected override Result DoCommit()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return DoCommit(updateTimeStamp: true).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long GetCounterForBundledCommit()
|
public long GetCounterForBundledCommit()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.GetCounterForBundledCommit();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoCommitProvisionally(long counter)
|
protected override Result DoCommitProvisionally(long counter)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using ScopedLock<SdkMutex> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||||
|
|
||||||
|
if (!_canCommitProvisionally)
|
||||||
|
return ResultFs.UnsupportedCommitProvisionallyForSaveDataFileSystem.Log();
|
||||||
|
|
||||||
|
return _saveFsDriver.CommitProvisionally(counter).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoRollback()
|
protected override Result DoRollback()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using ScopedLock<SdkMutex> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||||
|
|
||||||
|
return _saveFsDriver.Rollback().Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoGetFreeSpaceSize(out long freeSpace, ref readonly Path path)
|
protected override Result DoGetFreeSpaceSize(out long freeSpace, ref readonly Path path)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.GetFreeSpaceSize(out freeSpace, in path).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoGetTotalSpaceSize(out long totalSpace, ref readonly Path path)
|
protected override Result DoGetTotalSpaceSize(out long totalSpace, ref readonly Path path)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.GetTotalSpaceSize(out totalSpace, in path).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Result DoGetFileSystemAttribute(out FileSystemAttribute outAttribute)
|
protected override Result DoGetFileSystemAttribute(out FileSystemAttribute outAttribute)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.GetFileSystemAttribute(out outAttribute).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result WriteExtraData(in SaveDataExtraData extraData)
|
public override Result WriteExtraData(in SaveDataExtraData extraData)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver.WriteExtraData(in Unsafe.As<SaveDataExtraData, JournalIntegritySaveDataFileSystem.ExtraData>(ref Unsafe.AsRef(in extraData))).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result CommitExtraData(bool updateTimeStamp)
|
public override Result CommitExtraData(bool updateTimeStamp)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return DoCommit(updateTimeStamp).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result ReadExtraData(out SaveDataExtraData extraData)
|
public override Result ReadExtraData(out SaveDataExtraData extraData)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
UnsafeHelpers.SkipParamInit(out extraData);
|
||||||
|
_saveFsDriver.ReadExtraData(out Unsafe.As<SaveDataExtraData, JournalIntegritySaveDataFileSystem.ExtraData>(ref extraData));
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void RegisterExtraDataAccessorObserver(ISaveDataExtraDataAccessorObserver observer, SaveDataSpaceId spaceId, ulong saveDataId)
|
public override void RegisterExtraDataAccessorObserver(ISaveDataExtraDataAccessorObserver observer,
|
||||||
|
SaveDataSpaceId spaceId, ulong saveDataId)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_cacheObserver = observer;
|
||||||
|
_spaceId = spaceId;
|
||||||
|
_saveDataId = saveDataId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsSaveDataFileSystemCacheEnabled()
|
public override bool IsSaveDataFileSystemCacheEnabled()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result RollbackOnlyModified()
|
public override Result RollbackOnlyModified()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using ScopedLock<SdkMutex> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||||
|
|
||||||
|
return _saveFsDriver.RollbackOnlyModified().Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IInternalStorageFileSystem GetInternalStorageFileSystem()
|
public IInternalStorageFileSystem GetInternalStorageFileSystem()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _saveFsDriver;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,7 +9,7 @@ namespace LibHac.FsSystem;
|
||||||
/// Wraps an <see cref="IFile"/>, converting its returned <see cref="Result"/>s
|
/// Wraps an <see cref="IFile"/>, converting its returned <see cref="Result"/>s
|
||||||
/// to save-data-specific <see cref="Result"/>s.
|
/// to save-data-specific <see cref="Result"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>Based on nnSdk 14.3.0 (FS 14.1.0)</remarks>
|
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||||
public class SaveDataResultConvertFile : IResultConvertFile
|
public class SaveDataResultConvertFile : IResultConvertFile
|
||||||
{
|
{
|
||||||
private bool _isReconstructible;
|
private bool _isReconstructible;
|
||||||
|
@ -29,13 +29,13 @@ public class SaveDataResultConvertFile : IResultConvertFile
|
||||||
/// Wraps an <see cref="IDirectory"/>, converting its returned <see cref="Result"/>s
|
/// Wraps an <see cref="IDirectory"/>, converting its returned <see cref="Result"/>s
|
||||||
/// to save-data-specific <see cref="Result"/>s.
|
/// to save-data-specific <see cref="Result"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>Based on nnSdk 14.3.0 (FS 14.1.0)</remarks>
|
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||||
public class SaveDataResultConvertDirectory : IResultConvertDirectory
|
public class SaveDataResultConvertDirectory : IResultConvertDirectory
|
||||||
{
|
{
|
||||||
private bool _isReconstructible;
|
private bool _isReconstructible;
|
||||||
|
|
||||||
public SaveDataResultConvertDirectory(ref UniqueRef<IDirectory> baseDirectory, bool isReconstructible) : base(
|
public SaveDataResultConvertDirectory(ref UniqueRef<IDirectory> baseDirectory, bool isReconstructible)
|
||||||
ref baseDirectory)
|
: base(ref baseDirectory)
|
||||||
{
|
{
|
||||||
_isReconstructible = isReconstructible;
|
_isReconstructible = isReconstructible;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ public class SaveDataResultConvertDirectory : IResultConvertDirectory
|
||||||
/// Wraps an <see cref="ISaveDataFileSystem"/>, converting its returned <see cref="Result"/>s
|
/// Wraps an <see cref="ISaveDataFileSystem"/>, converting its returned <see cref="Result"/>s
|
||||||
/// to save-data-specific <see cref="Result"/>s.
|
/// to save-data-specific <see cref="Result"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>Based on nnSdk 14.3.0 (FS 14.1.0)</remarks>
|
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||||
public class SaveDataResultConvertFileSystem : IResultConvertFileSystem<ISaveDataFileSystem>
|
public class SaveDataResultConvertFileSystem : IResultConvertFileSystem<ISaveDataFileSystem>
|
||||||
{
|
{
|
||||||
private bool _isReconstructible;
|
private bool _isReconstructible;
|
||||||
|
|
|
@ -112,7 +112,7 @@ public class SwitchStorage : IStorage
|
||||||
/// the provided <see cref="Region"/> will be forwarded to one <see cref="IStorage"/>, and requests outside
|
/// the provided <see cref="Region"/> will be forwarded to one <see cref="IStorage"/>, and requests outside
|
||||||
/// will be forwarded to the other.
|
/// will be forwarded to the other.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>Based on nnSdk 14.3.0 (FS 14.1.0)</remarks>
|
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||||
public class RegionSwitchStorage : IStorage
|
public class RegionSwitchStorage : IStorage
|
||||||
{
|
{
|
||||||
public struct Region
|
public struct Region
|
||||||
|
|
Loading…
Reference in a new issue