diff --git a/src/LibHac/IO/LocalStorage.cs b/src/LibHac/IO/LocalStorage.cs new file mode 100644 index 00000000..dd08fe52 --- /dev/null +++ b/src/LibHac/IO/LocalStorage.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; + +namespace LibHac.IO +{ + public class LocalStorage : StorageBase + { + private string Path { get; } + private FileStream Stream { get; } + private StreamStorage Storage { get; } + + public LocalStorage(string path, FileAccess access) : this(path, access, FileMode.Open) { } + + public LocalStorage(string path, FileAccess access, FileMode mode) + { + Path = path; + Stream = new FileStream(Path, mode, access); + Storage = new StreamStorage(Stream, false); + + ToDispose.Add(Storage); + ToDispose.Add(Stream); + } + + protected override void ReadImpl(Span destination, long offset) + { + Storage.Read(destination, offset); + } + + protected override void WriteImpl(ReadOnlySpan source, long offset) + { + Storage.Write(source, offset); + } + + public override void Flush() + { + Storage.Flush(); + } + + public override long Length => Stream.Length; + } +} diff --git a/src/LibHac/IO/Save/SaveDataFileSystemCore.cs b/src/LibHac/IO/Save/SaveDataFileSystemCore.cs index cbe38891..22a108b3 100644 --- a/src/LibHac/IO/Save/SaveDataFileSystemCore.cs +++ b/src/LibHac/IO/Save/SaveDataFileSystemCore.cs @@ -54,8 +54,7 @@ namespace LibHac.IO.Save { if (file.BlockIndex < 0) { - // todo - return new MemoryStorage(new byte[0]); + return new NullStorage(0); } return OpenFatBlock(file.BlockIndex, file.FileSize); diff --git a/src/LibHac/Util.cs b/src/LibHac/Util.cs index de622738..5a93e623 100644 --- a/src/LibHac/Util.cs +++ b/src/LibHac/Util.cs @@ -184,23 +184,6 @@ namespace LibHac return Encoding.UTF8.GetString(reader.ReadBytes(size), 0, size); } - // todo Maybe make less naive - public static string GetRelativePath(string path, string basePath) - { - var directory = new DirectoryInfo(basePath); - var file = new FileInfo(path); - - string fullDirectory = directory.FullName; - string fullFile = file.FullName; - - if (!fullFile.StartsWith(fullDirectory)) - { - throw new ArgumentException($"{nameof(path)} is not a subpath of {nameof(basePath)}"); - } - - return fullFile.Substring(fullDirectory.Length + 1); - } - private static bool TryHexToInt(char c, out int value) { switch (c) diff --git a/src/hactoolnet/ProcessDelta.cs b/src/hactoolnet/ProcessDelta.cs index 5e102091..85934724 100644 --- a/src/hactoolnet/ProcessDelta.cs +++ b/src/hactoolnet/ProcessDelta.cs @@ -15,7 +15,7 @@ namespace hactoolnet public static void Process(Context ctx) { - using (IStorage deltaFile = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read).AsStorage(false)) + using (IStorage deltaFile = new LocalStorage(ctx.Options.InFile, FileAccess.Read)) { IStorage deltaStorage = deltaFile; Span magic = stackalloc byte[4]; @@ -42,7 +42,7 @@ namespace hactoolnet if (ctx.Options.BaseFile != null) { - using (IStorage baseFile = new FileStream(ctx.Options.BaseFile, FileMode.Open, FileAccess.Read).AsStorage(false)) + using (IStorage baseFile = new LocalStorage(ctx.Options.BaseFile, FileAccess.Read)) { delta.SetBaseStorage(baseFile); diff --git a/src/hactoolnet/ProcessKip.cs b/src/hactoolnet/ProcessKip.cs index 613a91ac..854eab60 100644 --- a/src/hactoolnet/ProcessKip.cs +++ b/src/hactoolnet/ProcessKip.cs @@ -8,18 +8,18 @@ namespace hactoolnet { public static void ProcessKip1(Context ctx) { - using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read)) + using (var file = new LocalStorage(ctx.Options.InFile, FileAccess.Read)) { - var kip = new Kip(file.AsStorage()); + var kip = new Kip(file); kip.OpenRawFile(); } } public static void ProcessIni1(Context ctx) { - using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read)) + using (var file = new LocalStorage(ctx.Options.InFile, FileAccess.Read)) { - var ini1 = new Ini1(file.AsStorage()); + var ini1 = new Ini1(file); string outDir = ctx.Options.OutDir; diff --git a/src/hactoolnet/ProcessNca.cs b/src/hactoolnet/ProcessNca.cs index 34178784..ce3ee3cd 100644 --- a/src/hactoolnet/ProcessNca.cs +++ b/src/hactoolnet/ProcessNca.cs @@ -11,7 +11,7 @@ namespace hactoolnet { public static void Process(Context ctx) { - using (IStorage file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read).AsStorage(false)) + using (IStorage file = new LocalStorage(ctx.Options.InFile, FileAccess.Read)) { var nca = new Nca(ctx.Keyset, file, false); nca.ValidateMasterHashes(); @@ -19,7 +19,7 @@ namespace hactoolnet if (ctx.Options.BaseNca != null) { - IStorage baseFile = new FileStream(ctx.Options.BaseNca, FileMode.Open, FileAccess.Read).AsStorage(false); + IStorage baseFile = new LocalStorage(ctx.Options.BaseNca, FileAccess.Read); var baseNca = new Nca(ctx.Keyset, baseFile, false); nca.SetBaseNca(baseNca); } diff --git a/src/hactoolnet/ProcessNsp.cs b/src/hactoolnet/ProcessNsp.cs index 1c0a8a0b..8a7267b5 100644 --- a/src/hactoolnet/ProcessNsp.cs +++ b/src/hactoolnet/ProcessNsp.cs @@ -11,9 +11,9 @@ namespace hactoolnet { public static void Process(Context ctx) { - using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read)) + using (var file = new LocalStorage(ctx.Options.InFile, FileAccess.Read)) { - var pfs = new PartitionFileSystem(file.AsStorage()); + var pfs = new PartitionFileSystem(file); ctx.Logger.LogMessage(pfs.Print()); if (ctx.Options.OutDir != null) diff --git a/src/hactoolnet/ProcessPackage.cs b/src/hactoolnet/ProcessPackage.cs index 0d5e1cb5..5669bdce 100644 --- a/src/hactoolnet/ProcessPackage.cs +++ b/src/hactoolnet/ProcessPackage.cs @@ -10,9 +10,9 @@ namespace hactoolnet { public static void ProcessPk11(Context ctx) { - using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read)) + using (var file = new LocalStorage(ctx.Options.InFile, FileAccess.Read)) { - var package1 = new Package1(ctx.Keyset, file.AsStorage()); + var package1 = new Package1(ctx.Keyset, file); string outDir = ctx.Options.OutDir; if (outDir != null) @@ -29,7 +29,7 @@ namespace hactoolnet public static void ProcessPk21(Context ctx) { - using (var file = new CachedStorage(new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read).AsStorage(), 0x4000, 4, false)) + using (var file = new CachedStorage(new LocalStorage(ctx.Options.InFile, FileAccess.Read), 0x4000, 4, false)) { var package2 = new Package2(ctx.Keyset, file); diff --git a/src/hactoolnet/ProcessRomfs.cs b/src/hactoolnet/ProcessRomfs.cs index 27a07832..d06f8b21 100644 --- a/src/hactoolnet/ProcessRomfs.cs +++ b/src/hactoolnet/ProcessRomfs.cs @@ -8,9 +8,9 @@ namespace hactoolnet { public static void Process(Context ctx) { - using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read)) + using (var file = new LocalStorage(ctx.Options.InFile, FileAccess.Read)) { - var romfs = new RomFsFileSystem(file.AsStorage()); + var romfs = new RomFsFileSystem(file); Process(ctx, romfs); } } diff --git a/src/hactoolnet/ProcessSave.cs b/src/hactoolnet/ProcessSave.cs index f394fb8b..0537789a 100644 --- a/src/hactoolnet/ProcessSave.cs +++ b/src/hactoolnet/ProcessSave.cs @@ -12,9 +12,9 @@ namespace hactoolnet { public static void Process(Context ctx) { - using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.ReadWrite)) + using (var file = new LocalStorage(ctx.Options.InFile, FileAccess.ReadWrite)) { - var save = new SaveDataFileSystem(ctx.Keyset, file.AsStorage(), ctx.Options.IntegrityLevel, true); + var save = new SaveDataFileSystem(ctx.Keyset, file, ctx.Options.IntegrityLevel, true); if (ctx.Options.Validate) { @@ -99,7 +99,7 @@ namespace hactoolnet string destFilename = ctx.Options.ReplaceFileDest; if (!destFilename.StartsWith("/")) destFilename = '/' + destFilename; - using (IFile inFile = new FileStream(ctx.Options.ReplaceFileSource, FileMode.Open, FileAccess.Read).AsIFile(OpenMode.ReadWrite)) + using (IFile inFile = new LocalFile(ctx.Options.ReplaceFileSource, OpenMode.Read)) { using (IFile outFile = save.OpenFile(destFilename, OpenMode.ReadWrite)) { diff --git a/src/hactoolnet/ProcessXci.cs b/src/hactoolnet/ProcessXci.cs index dd4bb8eb..02b06b74 100644 --- a/src/hactoolnet/ProcessXci.cs +++ b/src/hactoolnet/ProcessXci.cs @@ -11,9 +11,9 @@ namespace hactoolnet { public static void Process(Context ctx) { - using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read)) + using (var file = new LocalStorage(ctx.Options.InFile, FileAccess.Read)) { - var xci = new Xci(ctx.Keyset, file.AsStorage()); + var xci = new Xci(ctx.Keyset, file); ctx.Logger.LogMessage(xci.Print());