Add read and write options to IFile interface

This commit is contained in:
Alex Barney 2019-06-04 23:32:19 -05:00
parent fbeaff8d88
commit 775478fa16
15 changed files with 85 additions and 35 deletions

View file

@ -44,7 +44,7 @@ namespace LibHac.Fs
return key; return key;
} }
public override int Read(Span<byte> destination, long offset) public override int Read(Span<byte> destination, long offset, ReadOption options)
{ {
int toRead = ValidateReadParamsAndGetSize(destination, offset); int toRead = ValidateReadParamsAndGetSize(destination, offset);
@ -53,11 +53,16 @@ namespace LibHac.Fs
return toRead; return toRead;
} }
public override void Write(ReadOnlySpan<byte> source, long offset) public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
{ {
ValidateWriteParams(source, offset); ValidateWriteParams(source, offset);
BaseStorage.Write(source, offset); BaseStorage.Write(source, offset);
if ((options & WriteOption.Flush) != 0)
{
Flush();
}
} }
public override void Flush() public override void Flush()

View file

@ -246,7 +246,7 @@ namespace LibHac.Fs
using (IFile file = BaseFileSystem.OpenFile(filePath, OpenMode.ReadWrite)) using (IFile file = BaseFileSystem.OpenFile(filePath, OpenMode.ReadWrite))
{ {
file.Write(header.ToBytes(false), 0); file.Write(header.ToBytes(false), 0, WriteOption.Flush);
} }
} }
} }

View file

@ -31,7 +31,7 @@ namespace LibHac.Fs
ToDispose.AddRange(Sources); ToDispose.AddRange(Sources);
} }
public override int Read(Span<byte> destination, long offset) public override int Read(Span<byte> destination, long offset, ReadOption options)
{ {
long inPos = offset; long inPos = offset;
int outPos = 0; int outPos = 0;
@ -45,7 +45,7 @@ namespace LibHac.Fs
long fileEndOffset = Math.Min((fileIndex + 1) * SubFileSize, GetSize()); long fileEndOffset = Math.Min((fileIndex + 1) * SubFileSize, GetSize());
int bytesToRead = (int)Math.Min(fileEndOffset - inPos, remaining); int bytesToRead = (int)Math.Min(fileEndOffset - inPos, remaining);
int bytesRead = file.Read(destination.Slice(outPos, bytesToRead), fileOffset); int bytesRead = file.Read(destination.Slice(outPos, bytesToRead), fileOffset, options);
outPos += bytesRead; outPos += bytesRead;
inPos += bytesRead; inPos += bytesRead;
@ -57,7 +57,7 @@ namespace LibHac.Fs
return outPos; return outPos;
} }
public override void Write(ReadOnlySpan<byte> source, long offset) public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
{ {
ValidateWriteParams(source, offset); ValidateWriteParams(source, offset);
@ -73,12 +73,17 @@ namespace LibHac.Fs
long fileEndOffset = Math.Min((fileIndex + 1) * SubFileSize, GetSize()); long fileEndOffset = Math.Min((fileIndex + 1) * SubFileSize, GetSize());
int bytesToWrite = (int)Math.Min(fileEndOffset - outPos, remaining); int bytesToWrite = (int)Math.Min(fileEndOffset - outPos, remaining);
file.Write(source.Slice(inPos, bytesToWrite), fileOffset); file.Write(source.Slice(inPos, bytesToWrite), fileOffset, options);
outPos += bytesToWrite; outPos += bytesToWrite;
inPos += bytesToWrite; inPos += bytesToWrite;
remaining -= bytesToWrite; remaining -= bytesToWrite;
} }
if ((options & WriteOption.Flush) != 0)
{
Flush();
}
} }
public override void Flush() public override void Flush()

View file

@ -16,14 +16,14 @@ namespace LibHac.Fs
ToDispose.Add(BaseFile); ToDispose.Add(BaseFile);
} }
public override int Read(Span<byte> destination, long offset) public override int Read(Span<byte> destination, long offset, ReadOption options)
{ {
return BaseFile.Read(destination, offset); return BaseFile.Read(destination, offset, options);
} }
public override void Write(ReadOnlySpan<byte> source, long offset) public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
{ {
BaseFile.Write(source, offset); BaseFile.Write(source, offset, options);
} }
public override void Flush() public override void Flush()

View file

@ -8,8 +8,8 @@ namespace LibHac.Fs
protected bool IsDisposed { get; private set; } protected bool IsDisposed { get; private set; }
internal List<IDisposable> ToDispose { get; } = new List<IDisposable>(); internal List<IDisposable> ToDispose { get; } = new List<IDisposable>();
public abstract int Read(Span<byte> destination, long offset); public abstract int Read(Span<byte> destination, long offset, ReadOption options);
public abstract void Write(ReadOnlySpan<byte> source, long offset); public abstract void Write(ReadOnlySpan<byte> source, long offset, WriteOption options);
public abstract void Flush(); public abstract void Flush();
public abstract long GetSize(); public abstract long GetSize();
public abstract void SetSize(long size); public abstract void SetSize(long size);
@ -90,4 +90,17 @@ namespace LibHac.Fs
Append = 4, Append = 4,
ReadWrite = Read | Write ReadWrite = Read | Write
} }
[Flags]
public enum ReadOption
{
None = 0
}
[Flags]
public enum WriteOption
{
None = 0,
Flush = 1
}
} }

View file

@ -204,6 +204,16 @@ namespace LibHac.Fs
} }
} }
} }
public static int Read(this IFile file, Span<byte> destination, long offset)
{
return file.Read(destination, offset, ReadOption.None);
}
public static void Write(this IFile file, ReadOnlySpan<byte> source, long offset)
{
file.Write(source, offset, WriteOption.None);
}
} }
[Flags] [Flags]

View file

@ -29,20 +29,22 @@ namespace LibHac.Fs
/// <param name="destination">The buffer where the read bytes will be stored. /// <param name="destination">The buffer where the read bytes will be stored.
/// The number of bytes read will be no larger than the length of the buffer.</param> /// The number of bytes read will be no larger than the length of the buffer.</param>
/// <param name="offset">The offset in the <see cref="IFile"/> at which to begin reading.</param> /// <param name="offset">The offset in the <see cref="IFile"/> at which to begin reading.</param>
/// <param name="options">Options for reading from the <see cref="IFile"/>.</param>
/// <returns>The total number of bytes read into the buffer. This can be less than the /// <returns>The total number of bytes read into the buffer. This can be less than the
/// size of the buffer if the IFile is too short to fulfill the request.</returns> /// size of the buffer if the IFile is too short to fulfill the request.</returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> is invalid.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> is invalid.</exception>
/// <exception cref="NotSupportedException">The file's <see cref="OpenMode"/> does not allow reading.</exception> /// <exception cref="NotSupportedException">The file's <see cref="OpenMode"/> does not allow reading.</exception>
int Read(Span<byte> destination, long offset); int Read(Span<byte> destination, long offset, ReadOption options);
/// <summary> /// <summary>
/// Writes a sequence of bytes to the current <see cref="IFile"/>. /// Writes a sequence of bytes to the current <see cref="IFile"/>.
/// </summary> /// </summary>
/// <param name="source">The buffer containing the bytes to be written.</param> /// <param name="source">The buffer containing the bytes to be written.</param>
/// <param name="offset">The offset in the <see cref="IStorage"/> at which to begin writing.</param> /// <param name="offset">The offset in the <see cref="IStorage"/> at which to begin writing.</param>
/// <param name="options">Options for writing to the <see cref="IFile"/>.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> is negative.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> is negative.</exception>
/// <exception cref="NotSupportedException">The file's <see cref="OpenMode"/> does not allow this request.</exception> /// <exception cref="NotSupportedException">The file's <see cref="OpenMode"/> does not allow this request.</exception>
void Write(ReadOnlySpan<byte> source, long offset); void Write(ReadOnlySpan<byte> source, long offset, WriteOption options);
/// <summary> /// <summary>
/// Causes any buffered data to be written to the underlying device. /// Causes any buffered data to be written to the underlying device.

View file

@ -20,20 +20,20 @@ namespace LibHac.Fs
ToDispose.Add(Stream); ToDispose.Add(Stream);
} }
public override int Read(Span<byte> destination, long offset) public override int Read(Span<byte> destination, long offset, ReadOption options)
{ {
int toRead = ValidateReadParamsAndGetSize(destination, offset); int toRead = ValidateReadParamsAndGetSize(destination, offset);
File.Read(destination.Slice(0, toRead), offset); File.Read(destination.Slice(0, toRead), offset, options);
return toRead; return toRead;
} }
public override void Write(ReadOnlySpan<byte> source, long offset) public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
{ {
ValidateWriteParams(source, offset); ValidateWriteParams(source, offset);
File.Write(source, offset); File.Write(source, offset, options);
} }
public override void Flush() public override void Flush()

View file

@ -13,14 +13,14 @@ namespace LibHac.Fs
private long Length { get; } private long Length { get; }
public override int Read(Span<byte> destination, long offset) public override int Read(Span<byte> destination, long offset, ReadOption options)
{ {
int toRead = ValidateReadParamsAndGetSize(destination, offset); int toRead = ValidateReadParamsAndGetSize(destination, offset);
destination.Slice(0, toRead).Clear(); destination.Slice(0, toRead).Clear();
return toRead; return toRead;
} }
public override void Write(ReadOnlySpan<byte> source, long offset) public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
{ {
} }

View file

@ -16,7 +16,7 @@ namespace LibHac.Fs
Size = size; Size = size;
} }
public override int Read(Span<byte> destination, long offset) public override int Read(Span<byte> destination, long offset, ReadOption options)
{ {
int toRead = ValidateReadParamsAndGetSize(destination, offset); int toRead = ValidateReadParamsAndGetSize(destination, offset);
@ -26,7 +26,7 @@ namespace LibHac.Fs
return toRead; return toRead;
} }
public override void Write(ReadOnlySpan<byte> source, long offset) public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View file

@ -11,9 +11,9 @@ namespace LibHac.Fs
BaseFile = baseFile; BaseFile = baseFile;
} }
public override int Read(Span<byte> destination, long offset) public override int Read(Span<byte> destination, long offset, ReadOption options)
{ {
return BaseFile.Read(destination, offset); return BaseFile.Read(destination, offset, options);
} }
public override long GetSize() public override long GetSize()
@ -22,7 +22,7 @@ namespace LibHac.Fs
} }
public override void Flush() { } public override void Flush() { }
public override void Write(ReadOnlySpan<byte> source, long offset) => throw new NotSupportedException(); public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options) => throw new NotSupportedException();
public override void SetSize(long size) => throw new NotSupportedException(); public override void SetSize(long size) => throw new NotSupportedException();
} }
} }

View file

@ -16,7 +16,7 @@ namespace LibHac.Fs.RomFs
Size = size; Size = size;
} }
public override int Read(Span<byte> destination, long offset) public override int Read(Span<byte> destination, long offset, ReadOption options)
{ {
int toRead = ValidateReadParamsAndGetSize(destination, offset); int toRead = ValidateReadParamsAndGetSize(destination, offset);
@ -26,7 +26,7 @@ namespace LibHac.Fs.RomFs
return toRead; return toRead;
} }
public override void Write(ReadOnlySpan<byte> source, long offset) public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View file

@ -19,7 +19,7 @@ namespace LibHac.Fs.Save
Size = size; Size = size;
} }
public override int Read(Span<byte> destination, long offset) public override int Read(Span<byte> destination, long offset, ReadOption options)
{ {
int toRead = ValidateReadParamsAndGetSize(destination, offset); int toRead = ValidateReadParamsAndGetSize(destination, offset);
@ -28,11 +28,16 @@ namespace LibHac.Fs.Save
return toRead; return toRead;
} }
public override void Write(ReadOnlySpan<byte> source, long offset) public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
{ {
ValidateWriteParams(source, offset); ValidateWriteParams(source, offset);
BaseStorage.Write(source, offset); BaseStorage.Write(source, offset);
if ((options & WriteOption.Flush) != 0)
{
Flush();
}
} }
public override void Flush() public override void Flush()

View file

@ -12,7 +12,7 @@ namespace LibHac.Fs
Mode = mode; Mode = mode;
} }
public override int Read(Span<byte> destination, long offset) public override int Read(Span<byte> destination, long offset, ReadOption options)
{ {
int toRead = ValidateReadParamsAndGetSize(destination, offset); int toRead = ValidateReadParamsAndGetSize(destination, offset);
@ -21,11 +21,16 @@ namespace LibHac.Fs
return toRead; return toRead;
} }
public override void Write(ReadOnlySpan<byte> source, long offset) public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
{ {
ValidateWriteParams(source, offset); ValidateWriteParams(source, offset);
BaseStorage.Write(source, offset); BaseStorage.Write(source, offset);
if ((options & WriteOption.Flush) != 0)
{
Flush();
}
} }
public override void Flush() public override void Flush()

View file

@ -21,7 +21,7 @@ namespace LibHac.Fs
Mode = mode; Mode = mode;
} }
public override int Read(Span<byte> destination, long offset) public override int Read(Span<byte> destination, long offset, ReadOption options)
{ {
#if STREAM_SPAN #if STREAM_SPAN
lock (Locker) lock (Locker)
@ -56,7 +56,7 @@ namespace LibHac.Fs
#endif #endif
} }
public override void Write(ReadOnlySpan<byte> source, long offset) public override void Write(ReadOnlySpan<byte> source, long offset, WriteOption options)
{ {
#if STREAM_SPAN #if STREAM_SPAN
lock (Locker) lock (Locker)
@ -78,6 +78,11 @@ namespace LibHac.Fs
} }
finally { ArrayPool<byte>.Shared.Return(buffer); } finally { ArrayPool<byte>.Shared.Return(buffer); }
#endif #endif
if ((options & WriteOption.Flush) != 0)
{
Flush();
}
} }
public override void Flush() public override void Flush()