diff --git a/src/LibHac/IO/Save/HierarchicalSaveFileTable.cs b/src/LibHac/IO/Save/HierarchicalSaveFileTable.cs index 4d9c7d25..994963da 100644 --- a/src/LibHac/IO/Save/HierarchicalSaveFileTable.cs +++ b/src/LibHac/IO/Save/HierarchicalSaveFileTable.cs @@ -95,14 +95,74 @@ namespace LibHac.IO.Save if (path == "/") throw new ArgumentException("Path cannot be empty"); - CreateFileRecursiveInternal(pathBytes, ref fileInfo); + CreateFileRecursive(pathBytes, ref fileInfo); } - private void CreateFileRecursiveInternal(ReadOnlySpan path, ref SaveFileInfo fileInfo) + public void AddDirectory(string path) + { + path = PathTools.Normalize(path); + ReadOnlySpan pathBytes = Util.GetUtf8Bytes(path); + + if (path == "/") throw new ArgumentException("Path cannot be empty"); + + SaveFindPosition emptyDir = default; + CreateDirectoryRecursive(pathBytes, ref emptyDir); + } + + private void CreateFileRecursive(ReadOnlySpan path, ref SaveFileInfo fileInfo) { var parser = new PathParser(path); var key = new SaveEntryKey(parser.GetCurrent(), 0); + int parentIndex = CreateParentDirectoryRecursive(ref parser, ref key); + + int index = FileTable.GetIndexFromKey(ref key).Index; + var fileEntry = new TableEntry(); + + if (index < 0) + { + index = FileTable.Add(ref key, ref fileEntry); + + DirectoryTable.GetValue(parentIndex, out TableEntry parentEntry); + + fileEntry.NextSibling = parentEntry.Value.NextFile; + parentEntry.Value.NextFile = index; + + DirectoryTable.SetValue(parentIndex, ref parentEntry); + } + + fileEntry.Value = fileInfo; + FileTable.SetValue(index, ref fileEntry); + } + + private void CreateDirectoryRecursive(ReadOnlySpan path, ref SaveFindPosition dirInfo) + { + var parser = new PathParser(path); + var key = new SaveEntryKey(parser.GetCurrent(), 0); + + int parentIndex = CreateParentDirectoryRecursive(ref parser, ref key); + + int index = DirectoryTable.GetIndexFromKey(ref key).Index; + var dirEntry = new TableEntry(); + + if (index < 0) + { + index = DirectoryTable.Add(ref key, ref dirEntry); + + DirectoryTable.GetValue(parentIndex, out TableEntry parentEntry); + + dirEntry.NextSibling = parentEntry.Value.NextDirectory; + parentEntry.Value.NextDirectory = index; + + DirectoryTable.SetValue(parentIndex, ref parentEntry); + } + + dirEntry.Value = dirInfo; + DirectoryTable.SetValue(index, ref dirEntry); + } + + private int CreateParentDirectoryRecursive(ref PathParser parser, ref SaveEntryKey key) + { int prevIndex = 0; while (!parser.IsFinished()) @@ -131,25 +191,7 @@ namespace LibHac.IO.Save parser.TryGetNext(out key.Name); } - { - int index = FileTable.GetIndexFromKey(ref key).Index; - var fileEntry = new TableEntry(); - - if (index < 0) - { - index = FileTable.Add(ref key, ref fileEntry); - - DirectoryTable.GetValue(prevIndex, out TableEntry parentEntry); - - fileEntry.NextSibling = parentEntry.Value.NextFile; - parentEntry.Value.NextFile = index; - - DirectoryTable.SetValue(prevIndex, ref parentEntry); - } - - fileEntry.Value = fileInfo; - FileTable.SetValue(index, ref fileEntry); - } + return prevIndex; } public void DeleteFile(string path) diff --git a/src/LibHac/IO/Save/SaveDataFileSystemCore.cs b/src/LibHac/IO/Save/SaveDataFileSystemCore.cs index beb45bb0..32f25abd 100644 --- a/src/LibHac/IO/Save/SaveDataFileSystemCore.cs +++ b/src/LibHac/IO/Save/SaveDataFileSystemCore.cs @@ -29,7 +29,9 @@ namespace LibHac.IO.Save public void CreateDirectory(string path) { - throw new NotImplementedException(); + path = PathTools.Normalize(path); + + FileTable.AddDirectory(path); } public void CreateFile(string path, long size, CreateFileOptions options)