diff --git a/build/CodeGen/results.csv b/build/CodeGen/results.csv
index 520d2e68..f6eeebe6 100644
--- a/build/CodeGen/results.csv
+++ b/build/CodeGen/results.csv
@@ -1069,6 +1069,7 @@ Module,DescriptionStart,DescriptionEnd,Flags,Namespace,Name,Summary
2,6396,,,,UnsupportedRollbackOnlyModifiedForDirectorySaveDataFileSystem,
2,6397,,,,UnsupportedOperateRangeForRegionSwitchStorage,
2,6398,,,,UnsupportedOperateRangeForSaveDataFile,
+2,6399,,,,UnsupportedOperateRangeForApplicationTemporaryFile,
2,6400,6449,,,PermissionDenied,
2,6403,,,,HostFileSystemOperationDisabled,Returned when opening a host FS on a retail device.
diff --git a/src/LibHac/Fs/ResultFs.cs b/src/LibHac/Fs/ResultFs.cs
index ad9fb24f..b6b9cdc5 100644
--- a/src/LibHac/Fs/ResultFs.cs
+++ b/src/LibHac/Fs/ResultFs.cs
@@ -1962,6 +1962,8 @@ public static class ResultFs
public static Result.Base UnsupportedOperateRangeForRegionSwitchStorage => new Result.Base(ModuleFs, 6397);
/// Error code: 2002-6398; Inner value: 0x31fc02
public static Result.Base UnsupportedOperateRangeForSaveDataFile => new Result.Base(ModuleFs, 6398);
+ /// Error code: 2002-6399; Inner value: 0x31fe02
+ public static Result.Base UnsupportedOperateRangeForApplicationTemporaryFile => new Result.Base(ModuleFs, 6399);
/// Error code: 2002-6400; Range: 6400-6449; Inner value: 0x320002
public static Result.Base PermissionDenied { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleFs, 6400, 6449); }
diff --git a/src/LibHac/FsSystem/ApplicationTemporaryFileSystem.cs b/src/LibHac/FsSystem/ApplicationTemporaryFileSystem.cs
index 0629c0f1..a3a61a29 100644
--- a/src/LibHac/FsSystem/ApplicationTemporaryFileSystem.cs
+++ b/src/LibHac/FsSystem/ApplicationTemporaryFileSystem.cs
@@ -1,7 +1,9 @@
// ReSharper disable UnusedMember.Local UnusedType.Local
#pragma warning disable CS0169 // Field is never used
using System;
+using System.Runtime.CompilerServices;
using LibHac.Common;
+using LibHac.Diag;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSystem.Save;
@@ -14,43 +16,75 @@ file class ApplicationTemporaryFile : IFile
public ApplicationTemporaryFile(ref UniqueRef file)
{
- throw new NotImplementedException();
+ _file = new UniqueRef(ref file);
+
+ Assert.SdkRequiresNotNull(in _file);
}
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 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 source, in WriteOption option)
{
- throw new NotImplementedException();
+ Assert.SdkRequiresNotNull(in _file);
+
+ return _file.Get.Write(offset, source, in option).Ret();
}
protected override Result DoFlush()
{
- throw new NotImplementedException();
+ Assert.SdkRequiresNotNull(in _file);
+
+ return _file.Get.Flush().Ret();
}
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)
{
- throw new NotImplementedException();
+ Assert.SdkRequiresNotNull(in _file);
+
+ return _file.Get.GetSize(out size).Ret();
}
protected override Result DoOperateRange(Span outBuffer, OperationId operationId, long offset, long size,
ReadOnlySpan inBuffer)
{
- throw new NotImplementedException();
+ Assert.SdkRequiresNotNull(in _file);
+
+ if (operationId == OperationId.InvalidateCache)
+ return ResultFs.UnsupportedOperateRangeForApplicationTemporaryFile.Log();
+
+ return _file.Get.OperateRange(outBuffer, operationId, offset, size, inBuffer).Ret();
}
}
@@ -65,140 +99,177 @@ public class ApplicationTemporaryFileSystem : ISaveDataFileSystem, ISaveDataExtr
public ApplicationTemporaryFileSystem()
{
- throw new NotImplementedException();
+ _baseStorage = new SharedRef();
+ _saveFsDriver = new IntegritySaveDataFileSystemDriver();
+ _isInitialized = false;
+ _cacheObserver = null;
}
public override void Dispose()
{
- throw new NotImplementedException();
+ if (_isInitialized)
+ {
+ _saveFsDriver.Commit().IgnoreResult();
+ _saveFsDriver.FinalizeObject();
+ _cacheObserver?.Unregister(_spaceId, _saveDataId);
+
+ _isInitialized = false;
+ }
+
+ _saveFsDriver.Dispose();
+ _baseStorage.Destroy();
+ base.Dispose();
}
public Result Initialize(IStorage baseStorage, IBufferManager bufferManager, IMacGenerator macGenerator,
IHash256GeneratorFactorySelector hashGeneratorFactorySelector)
{
- 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);
+ if (res.IsFailure()) return res.Miss();
+
+ _isInitialized = true;
+
+ return Result.Success;
}
public Result Initialize(ref readonly SharedRef baseStorage, IBufferManager bufferManager,
IMacGenerator macGenerator, IHash256GeneratorFactorySelector hashGeneratorFactorySelector)
{
- throw new NotImplementedException();
+ _baseStorage.SetByCopy(in baseStorage);
+
+ return Initialize(_baseStorage.Get, bufferManager, macGenerator, hashGeneratorFactorySelector).Ret();
}
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)
{
- throw new NotImplementedException();
+ return _saveFsDriver.DeleteFile(in path).Ret();
}
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)
{
- throw new NotImplementedException();
+ return _saveFsDriver.DeleteDirectory(in path).Ret();
}
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)
{
- throw new NotImplementedException();
+ return _saveFsDriver.CleanDirectoryRecursively(in path).Ret();
}
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)
{
- throw new NotImplementedException();
+ return _saveFsDriver.RenameDirectory(in currentPath, in newPath).Ret();
}
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 outFile, ref readonly Path path, OpenMode mode)
{
- throw new NotImplementedException();
+ using var file = new UniqueRef();
+ Result res = _saveFsDriver.OpenFile(ref file.Ref, in path, mode);
+ if (res.IsFailure()) return res.Miss();
+
+ using var wrapperFile = new UniqueRef(new ApplicationTemporaryFile(ref file.Ref));
+
+ outFile.Set(ref wrapperFile.Ref);
+ return Result.Success;
}
protected override Result DoOpenDirectory(ref UniqueRef outDirectory, ref readonly Path path,
OpenDirectoryMode mode)
{
- throw new NotImplementedException();
+ return _saveFsDriver.OpenDirectory(ref outDirectory, in path, mode).Ret();
}
protected override Result DoCommit()
{
- throw new NotImplementedException();
+ return _saveFsDriver.Commit().Ret();
}
protected override Result DoCommitProvisionally(long counter)
{
- throw new NotImplementedException();
+ return ResultFs.UnsupportedCommitProvisionallyForApplicationTemporaryFileSystem.Log();
}
protected override Result DoRollback()
{
- throw new NotImplementedException();
+ return Result.Success;
}
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)
{
- throw new NotImplementedException();
+ return _saveFsDriver.GetTotalSpaceSize(out totalSpace, in path).Ret();
}
public override bool IsSaveDataFileSystemCacheEnabled()
{
- throw new NotImplementedException();
+ return false;
}
public override Result RollbackOnlyModified()
{
- throw new NotImplementedException();
+ return ResultFs.UnsupportedRollbackOnlyModifiedForApplicationTemporaryFileSystem.Log();
}
protected override Result DoGetFileSystemAttribute(out FileSystemAttribute outAttribute)
{
- throw new NotImplementedException();
+ return _saveFsDriver.GetFileSystemAttribute(out outAttribute).Ret();
}
public override Result WriteExtraData(in SaveDataExtraData extraData)
{
- throw new NotImplementedException();
+ return _saveFsDriver.WriteExtraData(in Unsafe.As(ref Unsafe.AsRef(in extraData))).Ret();
}
public override Result CommitExtraData(bool updateTimeStamp)
{
- throw new NotImplementedException();
+ return DoCommit().Ret();
}
public override Result ReadExtraData(out SaveDataExtraData extraData)
{
- throw new NotImplementedException();
+ UnsafeHelpers.SkipParamInit(out extraData);
+ _saveFsDriver.ReadExtraData(out Unsafe.As(ref extraData));
+
+ return Result.Success;
}
public override void RegisterExtraDataAccessorObserver(ISaveDataExtraDataAccessorObserver observer, SaveDataSpaceId spaceId,
ulong saveDataId)
{
- throw new NotImplementedException();
+ _cacheObserver = observer;
+ _spaceId = spaceId;
+ _saveDataId = saveDataId;
}
}
\ No newline at end of file
diff --git a/src/LibHac/FsSystem/Save/IntegritySaveDataFileSystemDriver.cs b/src/LibHac/FsSystem/Save/IntegritySaveDataFileSystemDriver.cs
index 751443df..9b257ce3 100644
--- a/src/LibHac/FsSystem/Save/IntegritySaveDataFileSystemDriver.cs
+++ b/src/LibHac/FsSystem/Save/IntegritySaveDataFileSystemDriver.cs
@@ -66,7 +66,7 @@ public class IntegritySaveDataFileSystemDriver : ProxyFileSystemWithRetryingBuff
throw new NotImplementedException();
}
- public void WriteExtraData(in IntegritySaveDataFileSystem.ExtraData extraData)
+ public Result WriteExtraData(in IntegritySaveDataFileSystem.ExtraData extraData)
{
throw new NotImplementedException();
}