diff --git a/src/LibHac/FsService/ISaveDataIndexer.cs b/src/LibHac/FsService/ISaveDataIndexer.cs index f98eb759..9cdef710 100644 --- a/src/LibHac/FsService/ISaveDataIndexer.cs +++ b/src/LibHac/FsService/ISaveDataIndexer.cs @@ -3,23 +3,146 @@ using LibHac.Fs; namespace LibHac.FsService { + /// + /// Indexes save data metadata, holding key-value pairs of types and + /// respectively. + /// + /// + /// Each value contains information about the save data + /// including its size and current state, as well as its and save data + /// ID which represent the save data's storage location on disk. + /// public interface ISaveDataIndexer : IDisposable { + /// + /// Commit any changes made to the save data index. + /// + /// The of the operation. Result Commit(); + + /// + /// Rollback any changes made to the save data index since the last commit. + /// + /// The of the operation. Result Rollback(); + + /// + /// Remove all entries from the save data index and set the index to its initial state. + /// + /// The of the operation. Result Reset(); + + /// + /// Adds a new key to the index and returns the save data ID assigned to it. + /// The created value will only contain the assigned save data ID. + /// Fails if the key already exists. + /// + /// If the method returns successfully, contains the + /// save data ID assigned to the new entry. + /// Save data IDs are assigned using a counter that is incremented for each added save. + /// The key to add. + /// The of the operation. Result Publish(out ulong saveDataId, in SaveDataAttribute key); + + /// + /// Retrieves the for the specified key. + /// + /// If the method returns successfully, contains the + /// save data ID assigned to the new entry. + /// The key of the value to get. + /// The of the operation. Result Get(out SaveDataIndexerValue value, in SaveDataAttribute key); + + /// + /// Adds a key with a pre-specified static save data ID to the index. + /// + /// + /// Adding a save data ID that is already in the index is not allowed. Adding a static ID that might + /// conflict with a future dynamically-assigned ID should be avoided, otherwise there will be two saves + /// with the same ID. + /// FileSystemProxy avoids this by setting the high bit on static IDs. e.g. 0x8000000000000015 + /// + /// The key to add. + /// The of the operation. Result PutStaticSaveDataIdIndex(in SaveDataAttribute key); + + /// + /// Determines if there are any non-reserved entry slots remaining in the index. + /// + /// If the has a fixed number of entries, a portion of + /// those entries may be reserved for internal use, + /// if there are any non-reserved entries remaining, + /// otherwise . bool IsRemainedReservedOnly(); + + /// + /// Removes the save data with the specified save data ID from the index. + /// + /// The ID of the save to be removed. + /// The of the operation. Result Delete(ulong saveDataId); + + /// + /// Sets the in the specified save data's value. + /// + /// The save data ID of the save data to modify. + /// The new for the specified save data. + /// The of the operation. Result SetSpaceId(ulong saveDataId, SaveDataSpaceId spaceId); + + /// + /// Sets the size in the specified save data's value. + /// + /// The save data ID of the save data to modify. + /// The new size for the specified save data. + /// The of the operation. Result SetSize(ulong saveDataId, long size); + + /// + /// Sets the in the specified save data's value. + /// + /// The save data ID of the save data to modify. + /// The new for the specified save data. + /// The of the operation. Result SetState(ulong saveDataId, SaveDataState state); + + /// + /// Gets the key of the specified save data ID. + /// + /// If the method returns successfully, contains the + /// key of the specified save data ID. + /// The save data ID to locate. + /// The of the operation. Result GetKey(out SaveDataAttribute key, ulong saveDataId); + + /// + /// Gets the value of the specified save data ID. + /// + /// If the method returns successfully, contains the + /// value of the specified save data ID. + /// The save data ID to locate. + /// The of the operation. Result GetValue(out SaveDataIndexerValue value, ulong saveDataId); + + /// + /// Sets a new value to a key that already exists in the index. + /// + /// The key of the value to set. + /// The new value to associate with the specified key. + /// The of the operation. Result SetValue(in SaveDataAttribute key, in SaveDataIndexerValue value); + + /// + /// Gets the number of elements currently in the . + /// + /// The current element count. int GetIndexCount(); + + /// + /// Returns an that iterates through the . + /// + /// If the method returns successfully, contains the created . + /// The of the operation. Result OpenSaveDataInfoReader(out ReferenceCountedDisposable infoReader); } } \ No newline at end of file diff --git a/src/LibHac/FsService/ISaveDataInfoReader.cs b/src/LibHac/FsService/ISaveDataInfoReader.cs index 4f6fd3de..b31b32c3 100644 --- a/src/LibHac/FsService/ISaveDataInfoReader.cs +++ b/src/LibHac/FsService/ISaveDataInfoReader.cs @@ -1,9 +1,24 @@ using System; +using LibHac.Fs; namespace LibHac.FsService { + /// + /// Iterates through the of the save data + /// in a single save data space. + /// public interface ISaveDataInfoReader : IDisposable { + /// + /// Returns the next entries. This method will continue writing + /// entries to until there is either no more space + /// in the buffer, or until there are no more entries to iterate. + /// + /// If the method returns successfully, contains the number + /// of written to . + /// A value of 0 indicates that there are no more entries to iterate, or the buffer is too small. + /// The buffer in which to write the . + /// The of the operation. Result Read(out long readCount, Span saveDataInfoBuffer); } } \ No newline at end of file diff --git a/src/LibHac/FsService/SaveDataIndexer.cs b/src/LibHac/FsService/SaveDataIndexer.cs index fc24b9f4..915ff63c 100644 --- a/src/LibHac/FsService/SaveDataIndexer.cs +++ b/src/LibHac/FsService/SaveDataIndexer.cs @@ -12,6 +12,16 @@ using LibHac.Kvdb; namespace LibHac.FsService { + /// + /// Indexes metadata for persistent save data stored on disk, holding key-value pairs of types + /// and respectively. + /// + /// + /// Each manages one to two save data spaces. + /// Each save data space is identified by a , + /// and has its own unique storage location on disk.
+ /// Based on FS 10.0.0 (nnSdk 10.4.0) + ///
public class SaveDataIndexer : ISaveDataIndexer { private const int KvDatabaseCapacity = 0x1080; @@ -92,6 +102,12 @@ namespace LibHac.FsService Debug.Assert(!sb.Overflowed); } + /// + /// Generates a from the provided and . + /// + /// When this method returns, contains the generated . + /// The key used to generate the . + /// The value used to generate the . public static void GenerateSaveDataInfo(out SaveDataInfo info, in SaveDataAttribute key, in SaveDataIndexerValue value) { info = new SaveDataInfo @@ -701,6 +717,10 @@ namespace LibHac.FsService return Result.Success; } + /// + /// Mounts the storage for a , and unmounts the storage + /// when the is disposed; + /// private ref struct Mounter { private FileSystemClient FsClient { get; set; } diff --git a/src/LibHac/FsService/SaveDataIndexerLite.cs b/src/LibHac/FsService/SaveDataIndexerLite.cs index 855526c2..6550f26e 100644 --- a/src/LibHac/FsService/SaveDataIndexerLite.cs +++ b/src/LibHac/FsService/SaveDataIndexerLite.cs @@ -4,6 +4,15 @@ using LibHac.Fs; namespace LibHac.FsService { + /// + /// Indexes metadata for temporary save data, holding a key-value pair of types + /// and respectively. + /// + /// + /// Only one temporary save data may exist at a time. When a new + /// save data is added to the index, the existing key-value pair is replaced.
+ /// Based on FS 10.0.0 (nnSdk 10.4.0) + ///
public class SaveDataIndexerLite : ISaveDataIndexer { private object Locker { get; } = new object(); diff --git a/src/LibHac/FsService/SaveDataIndexerManager.cs b/src/LibHac/FsService/SaveDataIndexerManager.cs index d3d1f8e5..96c3de3d 100644 --- a/src/LibHac/FsService/SaveDataIndexerManager.cs +++ b/src/LibHac/FsService/SaveDataIndexerManager.cs @@ -7,6 +7,11 @@ using LibHac.FsService.Storage; namespace LibHac.FsService { + /// + /// Initializes and holds s for each save data space. + /// Creates accessors for individual SaveDataIndexers. + /// + /// Based on FS 10.0.0 (nnSdk 10.4.0) internal class SaveDataIndexerManager : ISaveDataIndexerManager { private FileSystemClient FsClient { get; } @@ -37,6 +42,18 @@ namespace LibHac.FsService _tempIndexer.Indexer = new SaveDataIndexerLite(); } + /// + /// Opens a for the specified save data space. + /// + /// + /// The returned will have exclusive access to the requested indexer. + /// The accessor must be disposed after use. + /// + /// If the method returns successfully, contains the created accessor. + /// If the method returns successfully, contains + /// if the indexer needed to be initialized. + /// The of the indexer to open. + /// The of the operation. public Result OpenAccessor(out SaveDataIndexerAccessor accessor, out bool neededInit, SaveDataSpaceId spaceId) { neededInit = false; @@ -200,6 +217,11 @@ namespace LibHac.FsService }; } + /// + /// Gives exclusive access to an . + /// Releases the lock to the upon disposal. + /// + /// Based on FS 10.0.0 (nnSdk 10.4.0) public class SaveDataIndexerAccessor : IDisposable { public ISaveDataIndexer Indexer { get; } diff --git a/src/LibHac/FsSystem/DirectorySaveDataFileSystem.cs b/src/LibHac/FsSystem/DirectorySaveDataFileSystem.cs index f6fadb93..4df71d68 100644 --- a/src/LibHac/FsSystem/DirectorySaveDataFileSystem.cs +++ b/src/LibHac/FsSystem/DirectorySaveDataFileSystem.cs @@ -10,8 +10,8 @@ namespace LibHac.FsSystem /// /// /// Transactional commits should be atomic as long as the function of the - /// underlying is atomic. - /// This class is based on nn::fssystem::DirectorySaveDataFileSystem in SDK 10.4.0 used in FS 10.0.0 + /// underlying is atomic.
+ /// Based on FS 10.0.0 (nnSdk 10.4.0) ///
public class DirectorySaveDataFileSystem : IFileSystem {