mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Remove the old FileBase class
This commit is contained in:
parent
6a449b7da1
commit
fd40b2fd77
15 changed files with 188 additions and 178 deletions
|
@ -3,7 +3,7 @@ using System.Threading;
|
|||
|
||||
namespace LibHac.Fs
|
||||
{
|
||||
public abstract class FileBase2 : IFile
|
||||
public abstract class FileBase : IFile
|
||||
{
|
||||
// 0 = not disposed; 1 = disposed
|
||||
private int _disposedState;
|
|
@ -3,7 +3,7 @@
|
|||
namespace LibHac.FsService
|
||||
{
|
||||
/// <summary>
|
||||
/// Permissions that control which storages or filesystems can be mounted or opened.
|
||||
/// Permissions that control which filesystems or storages can be mounted or opened.
|
||||
/// </summary>
|
||||
public enum AccessPermissions
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace LibHac.FsSystem
|
|||
private byte[] KekSeed { get; }
|
||||
private byte[] VerificationKey { get; }
|
||||
private int BlockSize { get; }
|
||||
private OpenMode Mode { get; }
|
||||
|
||||
private AesXtsFileHeader Header { get; }
|
||||
private IStorage BaseStorage { get; }
|
||||
|
@ -52,23 +53,31 @@ namespace LibHac.FsSystem
|
|||
return key;
|
||||
}
|
||||
|
||||
public override Result Read(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
public override Result ReadImpl(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
{
|
||||
bytesRead = default;
|
||||
|
||||
int toRead = ValidateReadParamsAndGetSize(destination, offset);
|
||||
Result rc = ValidateReadParams(out long toRead, offset, destination.Length, Mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Result rc = BaseStorage.Read(offset, destination.Slice(0, toRead));
|
||||
rc = BaseStorage.Read(offset, destination.Slice(0, (int)toRead));
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
{
|
||||
ValidateWriteParams(source, offset);
|
||||
Result rc = ValidateWriteParams(offset, source.Length, Mode, out bool isResizeNeeded);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Result rc = BaseStorage.Write(offset, source);
|
||||
if (isResizeNeeded)
|
||||
{
|
||||
rc = SetSizeImpl(offset + source.Length);
|
||||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
rc = BaseStorage.Write(offset, source);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if ((options & WriteOption.Flush) != 0)
|
||||
|
@ -79,18 +88,18 @@ namespace LibHac.FsSystem
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
public override Result FlushImpl()
|
||||
{
|
||||
return BaseStorage.Flush();
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
public override Result GetSizeImpl(out long size)
|
||||
{
|
||||
size = Header.Size;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
public override Result SetSizeImpl(long size)
|
||||
{
|
||||
Header.SetSize(size, VerificationKey);
|
||||
|
||||
|
@ -99,5 +108,13 @@ namespace LibHac.FsSystem
|
|||
|
||||
return BaseStorage.SetSize(size);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
BaseFile?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,8 +107,6 @@ namespace LibHac.FsSystem
|
|||
|
||||
var xtsFile = new AesXtsFile(mode, baseFile, path, KekSource, ValidationKey, BlockSize);
|
||||
|
||||
xtsFile.ToDispose.Add(baseFile);
|
||||
|
||||
file = xtsFile;
|
||||
return Result.Success;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace LibHac.FsSystem
|
|||
private string FilePath { get; }
|
||||
private List<IFile> Sources { get; }
|
||||
private long SubFileSize { get; }
|
||||
private OpenMode Mode { get; }
|
||||
|
||||
internal ConcatenationFile(IFileSystem baseFileSystem, string path, IEnumerable<IFile> sources, long subFileSize, OpenMode mode)
|
||||
{
|
||||
|
@ -30,17 +31,17 @@ namespace LibHac.FsSystem
|
|||
throw new ArgumentException($"Source file must have size {subFileSize}");
|
||||
}
|
||||
}
|
||||
|
||||
ToDispose.AddRange(Sources);
|
||||
}
|
||||
|
||||
public override Result Read(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
public override Result ReadImpl(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
{
|
||||
bytesRead = default;
|
||||
|
||||
long inPos = offset;
|
||||
int outPos = 0;
|
||||
int remaining = ValidateReadParamsAndGetSize(destination, offset);
|
||||
|
||||
Result rc = ValidateReadParams(out long remaining, offset, destination.Length, Mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
GetSize(out long fileSize).ThrowIfFailure();
|
||||
|
||||
|
@ -53,12 +54,12 @@ namespace LibHac.FsSystem
|
|||
long fileEndOffset = Math.Min((fileIndex + 1) * SubFileSize, fileSize);
|
||||
int bytesToRead = (int)Math.Min(fileEndOffset - inPos, remaining);
|
||||
|
||||
Result rc = file.Read(out long subFileBytesRead, fileOffset, destination.Slice(outPos, bytesToRead), options);
|
||||
rc = file.Read(out long subFileBytesRead, fileOffset, destination.Slice(outPos, bytesToRead), options);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
outPos += (int)subFileBytesRead;
|
||||
inPos += subFileBytesRead;
|
||||
remaining -= (int)subFileBytesRead;
|
||||
remaining -= subFileBytesRead;
|
||||
|
||||
if (bytesRead < bytesToRead) break;
|
||||
}
|
||||
|
@ -68,9 +69,10 @@ namespace LibHac.FsSystem
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
{
|
||||
ValidateWriteParams(source, offset);
|
||||
Result rc = ValidateWriteParams(offset, source.Length, Mode, out _);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
int inPos = 0;
|
||||
long outPos = offset;
|
||||
|
@ -87,7 +89,7 @@ namespace LibHac.FsSystem
|
|||
long fileEndOffset = Math.Min((fileIndex + 1) * SubFileSize, fileSize);
|
||||
int bytesToWrite = (int)Math.Min(fileEndOffset - outPos, remaining);
|
||||
|
||||
Result rc = file.Write(fileOffset, source.Slice(inPos, bytesToWrite), options);
|
||||
rc = file.Write(fileOffset, source.Slice(inPos, bytesToWrite), options);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
outPos += bytesToWrite;
|
||||
|
@ -95,7 +97,7 @@ namespace LibHac.FsSystem
|
|||
remaining -= bytesToWrite;
|
||||
}
|
||||
|
||||
if ((options & WriteOption.Flush) != 0)
|
||||
if (options.HasFlag(WriteOption.Flush))
|
||||
{
|
||||
return Flush();
|
||||
}
|
||||
|
@ -103,7 +105,7 @@ namespace LibHac.FsSystem
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
public override Result FlushImpl()
|
||||
{
|
||||
foreach (IFile file in Sources)
|
||||
{
|
||||
|
@ -114,7 +116,7 @@ namespace LibHac.FsSystem
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
public override Result GetSizeImpl(out long size)
|
||||
{
|
||||
size = default;
|
||||
|
||||
|
@ -129,7 +131,7 @@ namespace LibHac.FsSystem
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
public override Result SetSizeImpl(long size)
|
||||
{
|
||||
Result rc = GetSize(out long currentSize);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
@ -183,6 +185,19 @@ namespace LibHac.FsSystem
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
foreach (IFile file in Sources)
|
||||
{
|
||||
file?.Dispose();
|
||||
}
|
||||
|
||||
Sources.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private int GetSubFileIndexFromOffset(long offset)
|
||||
{
|
||||
return (int)(offset / SubFileSize);
|
||||
|
|
|
@ -3,7 +3,7 @@ using LibHac.Fs;
|
|||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
public class DirectorySaveDataFile : FileBase2
|
||||
public class DirectorySaveDataFile : FileBase
|
||||
{
|
||||
private IFile BaseFile { get; }
|
||||
private DirectorySaveDataFileSystem ParentFs { get; }
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
public abstract class FileBase : IFile
|
||||
{
|
||||
protected bool IsDisposed { get; private set; }
|
||||
internal List<IDisposable> ToDispose { get; } = new List<IDisposable>();
|
||||
|
||||
public abstract Result Read(out long bytesRead, long offset, Span<byte> destination, ReadOption options);
|
||||
public abstract Result Write(long offset, ReadOnlySpan<byte> source, WriteOption options);
|
||||
public abstract Result Flush();
|
||||
public abstract Result GetSize(out long size);
|
||||
public abstract Result SetSize(long size);
|
||||
|
||||
public OpenMode Mode { get; protected set; }
|
||||
|
||||
protected int ValidateReadParamsAndGetSize(ReadOnlySpan<byte> span, long offset)
|
||||
{
|
||||
if (IsDisposed) throw new ObjectDisposedException(null);
|
||||
|
||||
if ((Mode & OpenMode.Read) == 0) ThrowHelper.ThrowResult(ResultFs.InvalidOpenModeForRead, "File does not allow reading.");
|
||||
if (span == null) throw new ArgumentNullException(nameof(span));
|
||||
if (offset < 0) ThrowHelper.ThrowResult(ResultFs.ValueOutOfRange, "Offset must be non-negative.");
|
||||
|
||||
Result sizeResult = GetSize(out long fileSize);
|
||||
sizeResult.ThrowIfFailure();
|
||||
|
||||
int size = span.Length;
|
||||
|
||||
if (offset > fileSize) ThrowHelper.ThrowResult(ResultFs.ValueOutOfRange, "Offset must be less than the file size.");
|
||||
|
||||
return (int)Math.Min(fileSize - offset, size);
|
||||
}
|
||||
|
||||
protected void ValidateWriteParams(ReadOnlySpan<byte> span, long offset)
|
||||
{
|
||||
if (IsDisposed) throw new ObjectDisposedException(null);
|
||||
|
||||
if ((Mode & OpenMode.Write) == 0) ThrowHelper.ThrowResult(ResultFs.InvalidOpenModeForWrite, "File does not allow writing.");
|
||||
|
||||
if (span == null) throw new ArgumentNullException(nameof(span));
|
||||
if (offset < 0) ThrowHelper.ThrowResult(ResultFs.ValueOutOfRange, "Offset must be non-negative.");
|
||||
|
||||
Result sizeResult = GetSize(out long fileSize);
|
||||
sizeResult.ThrowIfFailure();
|
||||
|
||||
int size = span.Length;
|
||||
|
||||
if (offset + size > fileSize)
|
||||
{
|
||||
if ((Mode & OpenMode.AllowAppend) == 0)
|
||||
{
|
||||
ThrowHelper.ThrowResult(ResultFs.AllowAppendRequiredForImplicitExtension);
|
||||
}
|
||||
|
||||
SetSize(offset + size);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (IsDisposed) return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Flush();
|
||||
|
||||
foreach (IDisposable item in ToDispose)
|
||||
{
|
||||
item?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ using LibHac.Fs;
|
|||
|
||||
namespace LibHac.FsSystem
|
||||
{
|
||||
public class LocalFile : FileBase2
|
||||
public class LocalFile : FileBase
|
||||
{
|
||||
private const int ErrorHandleDiskFull = unchecked((int)0x80070027);
|
||||
private const int ErrorDiskFull = unchecked((int)0x80070070);
|
||||
|
|
|
@ -5,6 +5,8 @@ namespace LibHac.FsSystem
|
|||
{
|
||||
public class NullFile : FileBase
|
||||
{
|
||||
private OpenMode Mode { get; }
|
||||
|
||||
public NullFile()
|
||||
{
|
||||
Mode = OpenMode.ReadWrite;
|
||||
|
@ -14,32 +16,36 @@ namespace LibHac.FsSystem
|
|||
|
||||
private long Length { get; }
|
||||
|
||||
public override Result Read(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
public override Result ReadImpl(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
{
|
||||
int toRead = ValidateReadParamsAndGetSize(destination, offset);
|
||||
destination.Slice(0, toRead).Clear();
|
||||
bytesRead = 0;
|
||||
|
||||
Result rc = ValidateReadParams(out long toRead, offset, destination.Length, Mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
destination.Slice(0, (int)toRead).Clear();
|
||||
|
||||
bytesRead = toRead;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
{
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
public override Result FlushImpl()
|
||||
{
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
public override Result GetSizeImpl(out long size)
|
||||
{
|
||||
size = Length;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
public override Result SetSizeImpl(long size)
|
||||
{
|
||||
return ResultFs.UnsupportedOperation.Log();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace LibHac.FsSystem
|
|||
private IStorage BaseStorage { get; }
|
||||
private long Offset { get; }
|
||||
private long Size { get; }
|
||||
private OpenMode Mode { get; }
|
||||
|
||||
public PartitionFile(IStorage baseStorage, long offset, long size, OpenMode mode)
|
||||
{
|
||||
|
@ -17,27 +18,34 @@ namespace LibHac.FsSystem
|
|||
Size = size;
|
||||
}
|
||||
|
||||
public override Result Read(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
public override Result ReadImpl(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
{
|
||||
bytesRead = default;
|
||||
bytesRead = 0;
|
||||
|
||||
int toRead = ValidateReadParamsAndGetSize(destination, offset);
|
||||
Result rc = ValidateReadParams(out long toRead, offset, destination.Length, Mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
long storageOffset = Offset + offset;
|
||||
BaseStorage.Read(storageOffset, destination.Slice(0, toRead));
|
||||
BaseStorage.Read(storageOffset, destination.Slice(0, (int)toRead));
|
||||
|
||||
bytesRead = toRead;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
{
|
||||
ValidateWriteParams(source, offset);
|
||||
|
||||
Result rc = BaseStorage.Write(offset, source);
|
||||
Result rc = ValidateWriteParams(offset, source.Length, Mode, out bool isResizeNeeded);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if ((options & WriteOption.Flush) != 0)
|
||||
if (isResizeNeeded) return ResultFs.UnsupportedOperationInPartitionFileSetSize.Log();
|
||||
|
||||
if (offset > Size) return ResultFs.ValueOutOfRange.Log();
|
||||
|
||||
rc = BaseStorage.Write(offset, source);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
// N doesn't flush if the flag is set
|
||||
if (options.HasFlag(WriteOption.Flush))
|
||||
{
|
||||
return BaseStorage.Flush();
|
||||
}
|
||||
|
@ -45,9 +53,9 @@ namespace LibHac.FsSystem
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
public override Result FlushImpl()
|
||||
{
|
||||
if ((Mode & OpenMode.Write) != 0)
|
||||
if (!Mode.HasFlag(OpenMode.Write))
|
||||
{
|
||||
return BaseStorage.Flush();
|
||||
}
|
||||
|
@ -55,14 +63,19 @@ namespace LibHac.FsSystem
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
public override Result GetSizeImpl(out long size)
|
||||
{
|
||||
size = Size;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
public override Result SetSizeImpl(long size)
|
||||
{
|
||||
if (!Mode.HasFlag(OpenMode.Write))
|
||||
{
|
||||
return ResultFs.InvalidOpenModeForWrite.Log();
|
||||
}
|
||||
|
||||
return ResultFs.UnsupportedOperationInPartitionFileSetSize.Log();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,29 +12,29 @@ namespace LibHac.FsSystem
|
|||
BaseFile = baseFile;
|
||||
}
|
||||
|
||||
public override Result Read(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
public override Result ReadImpl(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
{
|
||||
return BaseFile.Read(out bytesRead, offset, destination, options);
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
public override Result GetSizeImpl(out long size)
|
||||
{
|
||||
return BaseFile.GetSize(out size);
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
public override Result FlushImpl()
|
||||
{
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
{
|
||||
return ResultFs.UnsupportedOperationModifyReadOnlyFile.Log();
|
||||
return ResultFs.InvalidOpenModeForWrite.Log();
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
public override Result SetSizeImpl(long size)
|
||||
{
|
||||
return ResultFs.UnsupportedOperationModifyReadOnlyFile.Log();
|
||||
return ResultFs.InvalidOpenModeForWrite.Log();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,21 +11,21 @@ namespace LibHac.FsSystem.RomFs
|
|||
|
||||
public RomFsFile(IStorage baseStorage, long offset, long size)
|
||||
{
|
||||
Mode = OpenMode.Read;
|
||||
BaseStorage = baseStorage;
|
||||
Offset = offset;
|
||||
Size = size;
|
||||
}
|
||||
|
||||
public override Result Read(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
public override Result ReadImpl(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
{
|
||||
bytesRead = default;
|
||||
|
||||
int toRead = ValidateReadParamsAndGetSize(destination, offset);
|
||||
Result rc = ValidateReadParams(out long toRead, offset, destination.Length, OpenMode.Read);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
long storageOffset = Offset + offset;
|
||||
|
||||
Result rc = BaseStorage.Read(storageOffset, destination.Slice(0, toRead));
|
||||
rc = BaseStorage.Read(storageOffset, destination.Slice(0, (int)toRead));
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
bytesRead = toRead;
|
||||
|
@ -33,23 +33,23 @@ namespace LibHac.FsSystem.RomFs
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
{
|
||||
return ResultFs.UnsupportedOperationModifyRomFsFile.Log();
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
public override Result FlushImpl()
|
||||
{
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
public override Result GetSizeImpl(out long size)
|
||||
{
|
||||
size = Size;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
public override Result SetSizeImpl(long size)
|
||||
{
|
||||
return ResultFs.UnsupportedOperationModifyRomFsFile.Log();
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace LibHac.FsSystem.Save
|
|||
private string Path { get; }
|
||||
private HierarchicalSaveFileTable FileTable { get; }
|
||||
private long Size { get; set; }
|
||||
private OpenMode Mode { get; }
|
||||
|
||||
public SaveDataFile(AllocationTableStorage baseStorage, string path, HierarchicalSaveFileTable fileTable, long size, OpenMode mode)
|
||||
{
|
||||
|
@ -20,22 +21,36 @@ namespace LibHac.FsSystem.Save
|
|||
Size = size;
|
||||
}
|
||||
|
||||
public override Result Read(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
public override Result ReadImpl(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
{
|
||||
bytesRead = default;
|
||||
|
||||
int toRead = ValidateReadParamsAndGetSize(destination, offset);
|
||||
Result rc = ValidateReadParams(out long toRead, offset, destination.Length, Mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Result rc = BaseStorage.Read(offset, destination.Slice(0, toRead));
|
||||
if (toRead == 0)
|
||||
{
|
||||
bytesRead = 0;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
rc = BaseStorage.Read(offset, destination.Slice(0, (int)toRead));
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
bytesRead = toRead;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
{
|
||||
ValidateWriteParams(source, offset);
|
||||
Result rc = ValidateWriteParams(offset, source.Length, Mode, out bool isResizeNeeded);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (isResizeNeeded)
|
||||
{
|
||||
rc = SetSizeImpl(offset + source.Length);
|
||||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
BaseStorage.Write(offset, source);
|
||||
|
||||
|
@ -47,18 +62,18 @@ namespace LibHac.FsSystem.Save
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
public override Result FlushImpl()
|
||||
{
|
||||
return BaseStorage.Flush();
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
public override Result GetSizeImpl(out long size)
|
||||
{
|
||||
size = Size;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
public override Result SetSizeImpl(long size)
|
||||
{
|
||||
if (size < 0) throw new ArgumentOutOfRangeException(nameof(size));
|
||||
if (Size == size) return Result.Success;
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace LibHac.FsSystem
|
|||
public class StorageFile : FileBase
|
||||
{
|
||||
private IStorage BaseStorage { get; }
|
||||
private OpenMode Mode { get; }
|
||||
|
||||
public StorageFile(IStorage baseStorage, OpenMode mode)
|
||||
{
|
||||
|
@ -13,26 +14,41 @@ namespace LibHac.FsSystem
|
|||
Mode = mode;
|
||||
}
|
||||
|
||||
public override Result Read(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
public override Result ReadImpl(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
{
|
||||
bytesRead = default;
|
||||
int toRead = ValidateReadParamsAndGetSize(destination, offset);
|
||||
|
||||
Result rc = BaseStorage.Read(offset, destination.Slice(0, toRead));
|
||||
Result rc = ValidateReadParams(out long toRead, offset, destination.Length, Mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (toRead == 0)
|
||||
{
|
||||
bytesRead = 0;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
rc = BaseStorage.Read(offset, destination.Slice(0, (int)toRead));
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
bytesRead = toRead;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
{
|
||||
ValidateWriteParams(source, offset);
|
||||
|
||||
Result rc = BaseStorage.Write(offset, source);
|
||||
Result rc = ValidateWriteParams(offset, source.Length, Mode, out bool isResizeNeeded);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if ((options & WriteOption.Flush) != 0)
|
||||
if (isResizeNeeded)
|
||||
{
|
||||
rc = SetSizeImpl(offset + source.Length);
|
||||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
rc = BaseStorage.Write(offset, source);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (options.HasFlag(WriteOption.Flush))
|
||||
{
|
||||
return Flush();
|
||||
}
|
||||
|
@ -40,18 +56,24 @@ namespace LibHac.FsSystem
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
public override Result FlushImpl()
|
||||
{
|
||||
if (!Mode.HasFlag(OpenMode.Write))
|
||||
return Result.Success;
|
||||
|
||||
return BaseStorage.Flush();
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
public override Result GetSizeImpl(out long size)
|
||||
{
|
||||
return BaseStorage.GetSize(out size);
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
public override Result SetSizeImpl(long size)
|
||||
{
|
||||
if (!Mode.HasFlag(OpenMode.Write))
|
||||
return ResultFs.InvalidOpenModeForWrite.Log();
|
||||
|
||||
return BaseStorage.SetSize(size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using LibHac.Fs;
|
||||
|
||||
#if !STREAM_SPAN
|
||||
using System.Buffers;
|
||||
#endif
|
||||
|
@ -14,6 +15,7 @@ namespace LibHac.FsSystem
|
|||
{
|
||||
// todo: handle Stream exceptions
|
||||
|
||||
private OpenMode Mode { get; }
|
||||
private Stream BaseStream { get; }
|
||||
private object Locker { get; } = new object();
|
||||
|
||||
|
@ -23,8 +25,13 @@ namespace LibHac.FsSystem
|
|||
Mode = mode;
|
||||
}
|
||||
|
||||
public override Result Read(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
public override Result ReadImpl(out long bytesRead, long offset, Span<byte> destination, ReadOption options)
|
||||
{
|
||||
bytesRead = default;
|
||||
|
||||
Result rc = ValidateReadParams(out long toRead, offset, destination.Length, Mode);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
#if STREAM_SPAN
|
||||
lock (Locker)
|
||||
{
|
||||
|
@ -33,11 +40,11 @@ namespace LibHac.FsSystem
|
|||
BaseStream.Position = offset;
|
||||
}
|
||||
|
||||
bytesRead = BaseStream.Read(destination);
|
||||
bytesRead = BaseStream.Read(destination.Slice(0, (int)toRead));
|
||||
return Result.Success;
|
||||
}
|
||||
#else
|
||||
byte[] buffer = ArrayPool<byte>.Shared.Rent(destination.Length);
|
||||
byte[] buffer = ArrayPool<byte>.Shared.Rent((int)toRead);
|
||||
try
|
||||
{
|
||||
lock (Locker)
|
||||
|
@ -47,10 +54,10 @@ namespace LibHac.FsSystem
|
|||
BaseStream.Position = offset;
|
||||
}
|
||||
|
||||
bytesRead = BaseStream.Read(buffer, 0, destination.Length);
|
||||
bytesRead = BaseStream.Read(buffer, 0, (int)toRead);
|
||||
}
|
||||
|
||||
new Span<byte>(buffer, 0, destination.Length).CopyTo(destination);
|
||||
new Span<byte>(buffer, 0, (int)bytesRead).CopyTo(destination);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
@ -58,8 +65,11 @@ namespace LibHac.FsSystem
|
|||
#endif
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
public override Result WriteImpl(long offset, ReadOnlySpan<byte> source, WriteOption options)
|
||||
{
|
||||
Result rc = ValidateWriteParams(offset, source.Length, Mode, out _);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
#if STREAM_SPAN
|
||||
lock (Locker)
|
||||
{
|
||||
|
@ -81,7 +91,7 @@ namespace LibHac.FsSystem
|
|||
finally { ArrayPool<byte>.Shared.Return(buffer); }
|
||||
#endif
|
||||
|
||||
if ((options & WriteOption.Flush) != 0)
|
||||
if (options.HasFlag(WriteOption.Flush))
|
||||
{
|
||||
return Flush();
|
||||
}
|
||||
|
@ -89,7 +99,7 @@ namespace LibHac.FsSystem
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
public override Result FlushImpl()
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
|
@ -98,7 +108,7 @@ namespace LibHac.FsSystem
|
|||
}
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
public override Result GetSizeImpl(out long size)
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
|
@ -107,7 +117,7 @@ namespace LibHac.FsSystem
|
|||
}
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
public override Result SetSizeImpl(long size)
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue