diff --git a/src/LibHac/IO/PathParser.cs b/src/LibHac/IO/PathParser.cs index 2fdb4e3f..a081fa27 100644 --- a/src/LibHac/IO/PathParser.cs +++ b/src/LibHac/IO/PathParser.cs @@ -3,6 +3,11 @@ using System.Diagnostics; namespace LibHac.IO { + /// + /// Enumerates a file or directory path one segment at a time. + /// + /// When the parser is initialized + /// will return the root directory name, i.e. an empty string. public ref struct PathParser { private ReadOnlySpan _path; @@ -22,9 +27,16 @@ namespace LibHac.IO _path = path; _offset = 0; _length = 0; - _finished = false; + _finished = path.Length == 1; } + /// + /// Moves the iterator to the next segment in the path and gets the name of that segment. + /// + /// When this method returns, contains the path segment's name. + /// if the was able to + /// move to the next path segment. + /// if there are no remaining path segments. public bool TryGetNext(out ReadOnlySpan name) { bool success = MoveNext(); @@ -32,6 +44,12 @@ namespace LibHac.IO return success; } + /// + /// Moves the iterator to the next segment in the path. + /// + /// if the was able to + /// move to the next path segment. + /// if there are no remaining path segments. public bool MoveNext() { if (_finished) return false; @@ -50,11 +68,19 @@ namespace LibHac.IO return true; } + /// + /// Gets the current path segment's name. + /// + /// The current path segment. public ReadOnlySpan GetCurrent() { return _path.Slice(_offset, _length); } + /// + /// Checks if the current path segment is the final one. + /// + /// if the current path segment is the final one. public bool IsFinished() => _finished; } } diff --git a/src/LibHac/IO/RomFs/HierarchicalRomFileTable.cs b/src/LibHac/IO/RomFs/HierarchicalRomFileTable.cs index 64f2541b..3ca47d0c 100644 --- a/src/LibHac/IO/RomFs/HierarchicalRomFileTable.cs +++ b/src/LibHac/IO/RomFs/HierarchicalRomFileTable.cs @@ -206,7 +206,7 @@ namespace LibHac.IO.RomFs path = PathTools.Normalize(path); ReadOnlySpan pathBytes = Util.GetUtf8Bytes(path); - if(path == "/") throw new ArgumentException("Path cannot be empty"); + if (path == "/") throw new ArgumentException("Path cannot be empty"); CreateFileRecursiveInternal(pathBytes, ref fileInfo); } @@ -358,12 +358,13 @@ namespace LibHac.IO.RomFs private void FindPathRecursive(ReadOnlySpan path, out RomEntryKey key) { var parser = new PathParser(path); - key = default; + key = new RomEntryKey(parser.GetCurrent(), 0); - do + while (!parser.IsFinished()) { key.Parent = DirectoryTable.GetOffsetFromKey(ref key); - } while (parser.TryGetNext(out key.Name) && !parser.IsFinished()); + parser.TryGetNext(out key.Name); + } } [StructLayout(LayoutKind.Sequential, Pack = 4)] diff --git a/src/LibHac/IO/Save/HierarchicalSaveFileTable.cs b/src/LibHac/IO/Save/HierarchicalSaveFileTable.cs index fceaa472..3d3bb82a 100644 --- a/src/LibHac/IO/Save/HierarchicalSaveFileTable.cs +++ b/src/LibHac/IO/Save/HierarchicalSaveFileTable.cs @@ -100,12 +100,13 @@ namespace LibHac.IO.Save private void FindPathRecursive(ReadOnlySpan path, out SaveEntryKey key) { var parser = new PathParser(path); - key = default; + key = new SaveEntryKey(parser.GetCurrent(), 0); - do + while (!parser.IsFinished()) { key.Parent = DirectoryTable.GetOffsetFromKey(ref key); - } while (parser.TryGetNext(out key.Name) && !parser.IsFinished()); + parser.TryGetNext(out key.Name); + } } [StructLayout(LayoutKind.Sequential, Pack = 1)] diff --git a/src/LibHac/IO/Save/SaveFsList.cs b/src/LibHac/IO/Save/SaveFsList.cs index 0e091e7a..ad7af15a 100644 --- a/src/LibHac/IO/Save/SaveFsList.cs +++ b/src/LibHac/IO/Save/SaveFsList.cs @@ -27,7 +27,6 @@ namespace LibHac.IO.Save ref SaveFsEntry entry = ref GetEntryFromBytes(entryBytes); int capacity = GetListCapacity(); - int entryId = -1; ReadEntry(UsedListHeadIndex, entryBytes); @@ -35,16 +34,16 @@ namespace LibHac.IO.Save { if (entry.Next > capacity) throw new IndexOutOfRangeException("Save entry index out of range"); - entryId = entry.Next; + int entryId = entry.Next; ReadEntry(entry.Next, out entry); if (entry.Parent == key.Parent && Util.StringSpansEqual(name, key.Name)) { - break; + return entryId; } } - return entryId; + return -1; } public bool TryGetValue(ref SaveEntryKey key, out T value)