mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-11 12:54:15 +02:00
Stream buffering
This commit is contained in:
parent
2345d5d349
commit
4bf12e121c
11 changed files with 482 additions and 28 deletions
|
@ -215,10 +215,19 @@ namespace System
|
||||||
{
|
{
|
||||||
T mFirstElement;
|
T mFirstElement;
|
||||||
|
|
||||||
|
public T* Ptr
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return &mFirstElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public this()
|
public this()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
ref T GetRef(int idx)
|
ref T GetRef(int idx)
|
||||||
{
|
{
|
||||||
|
@ -330,6 +339,15 @@ namespace System
|
||||||
int_arsize mLength1;
|
int_arsize mLength1;
|
||||||
T mFirstElement;
|
T mFirstElement;
|
||||||
|
|
||||||
|
public T* Ptr
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return &mFirstElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Array GetSelf()
|
Array GetSelf()
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
|
@ -338,7 +356,7 @@ namespace System
|
||||||
public this()
|
public this()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetLength(int dim)
|
public int GetLength(int dim)
|
||||||
{
|
{
|
||||||
if (dim == 0)
|
if (dim == 0)
|
||||||
|
@ -447,6 +465,15 @@ namespace System
|
||||||
int_arsize mLength2;
|
int_arsize mLength2;
|
||||||
T mFirstElement;
|
T mFirstElement;
|
||||||
|
|
||||||
|
public T* Ptr
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return &mFirstElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Array GetSelf()
|
Array GetSelf()
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
|
@ -569,6 +596,15 @@ namespace System
|
||||||
int_arsize mLength3;
|
int_arsize mLength3;
|
||||||
T mFirstElement;
|
T mFirstElement;
|
||||||
|
|
||||||
|
public T* Ptr
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return &mFirstElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Array GetSelf()
|
Array GetSelf()
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
|
|
183
BeefLibs/corlib/src/IO/BufferedStream.bf
Normal file
183
BeefLibs/corlib/src/IO/BufferedStream.bf
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
namespace System.IO
|
||||||
|
{
|
||||||
|
abstract class BufferedStream : Stream
|
||||||
|
{
|
||||||
|
protected int64 mPos;
|
||||||
|
protected int64 mUnderlyingLength;
|
||||||
|
protected uint8[] mBuffer ~ delete _;
|
||||||
|
protected int64 mBufferPos = -Int32.MinValue;
|
||||||
|
protected int64 mBufferEnd = -Int32.MinValue;
|
||||||
|
protected int64 mWriteDirtyPos = -Int32.MinValue;
|
||||||
|
protected int64 mWriteDirtyEnd = -Int32.MinValue;
|
||||||
|
|
||||||
|
public override int64 Position
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
mPos = Math.Min(value, Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int64 Length
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
UpdateLength();
|
||||||
|
return Math.Max(mUnderlyingLength, mWriteDirtyEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void UpdateLength();
|
||||||
|
protected abstract Result<int> TryReadUnderlying(int64 pos, Span<uint8> data);
|
||||||
|
protected abstract Result<int> TryWriteUnderlying(int64 pos, Span<uint8> data);
|
||||||
|
|
||||||
|
public ~this()
|
||||||
|
{
|
||||||
|
Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Result<void> Seek(int64 pos, SeekKind seekKind = .Absolute)
|
||||||
|
{
|
||||||
|
int64 length = Length;
|
||||||
|
|
||||||
|
int64 newPos;
|
||||||
|
switch (seekKind)
|
||||||
|
{
|
||||||
|
case .Absolute:
|
||||||
|
mPos = Math.Min(pos, length);
|
||||||
|
if (pos > length)
|
||||||
|
return .Err;
|
||||||
|
case .FromEnd:
|
||||||
|
newPos = length - pos;
|
||||||
|
case .Relative:
|
||||||
|
mPos = Math.Min(mPos + pos, length);
|
||||||
|
}
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MakeBuffer(int size)
|
||||||
|
{
|
||||||
|
delete mBuffer;
|
||||||
|
mBuffer = new uint8[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Result<int> TryRead(Span<uint8> data)
|
||||||
|
{
|
||||||
|
int64 spaceLeft = mBufferEnd - mPos;
|
||||||
|
if (data.Length <= spaceLeft)
|
||||||
|
{
|
||||||
|
Internal.MemCpy(data.Ptr, mBuffer.Ptr + (mPos - mBufferPos), data.Length);
|
||||||
|
mPos += data.Length;
|
||||||
|
return data.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 readStart = mPos;
|
||||||
|
|
||||||
|
var data;
|
||||||
|
if (spaceLeft > 0)
|
||||||
|
{
|
||||||
|
Internal.MemCpy(data.Ptr, mBuffer.Ptr + (mPos - mBufferPos), spaceLeft);
|
||||||
|
mPos += spaceLeft;
|
||||||
|
data.RemoveFromStart(spaceLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mWriteDirtyPos >= 0)
|
||||||
|
Try!(Flush());
|
||||||
|
|
||||||
|
if ((mBuffer == null) || (data.Length > mBuffer.Count))
|
||||||
|
{
|
||||||
|
var result = TryReadUnderlying(mPos, data);
|
||||||
|
if (result case .Ok(let len))
|
||||||
|
mPos += len;
|
||||||
|
return mPos - readStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = TryReadUnderlying(mPos, mBuffer);
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case .Ok(let len):
|
||||||
|
mBufferPos = mPos;
|
||||||
|
mBufferEnd = mPos + len;
|
||||||
|
int readLen = Math.Min(len, data.Length);
|
||||||
|
Internal.MemCpy(data.Ptr, mBuffer.Ptr, readLen);
|
||||||
|
mPos += readLen;
|
||||||
|
return mPos - readStart;
|
||||||
|
case .Err:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Result<int> TryWrite(Span<uint8> data)
|
||||||
|
{
|
||||||
|
var data;
|
||||||
|
|
||||||
|
if ((mWriteDirtyEnd >= 0) && (mWriteDirtyEnd != mPos))
|
||||||
|
{
|
||||||
|
Try!(Flush());
|
||||||
|
}
|
||||||
|
|
||||||
|
int writeCount = 0;
|
||||||
|
if (mWriteDirtyEnd >= 0)
|
||||||
|
{
|
||||||
|
int64 spaceLeft = (mBufferPos + mBuffer.Count) - mPos;
|
||||||
|
if (data.Length <= spaceLeft)
|
||||||
|
writeCount = data.Length;
|
||||||
|
else
|
||||||
|
writeCount = spaceLeft;
|
||||||
|
|
||||||
|
if (writeCount > 0)
|
||||||
|
{
|
||||||
|
Internal.MemCpy(mBuffer.Ptr + (mPos - mBufferPos), data.Ptr, writeCount);
|
||||||
|
mPos += writeCount;
|
||||||
|
mWriteDirtyEnd = Math.Max(mWriteDirtyEnd, mPos);
|
||||||
|
mBufferEnd = Math.Max(mBufferEnd, mPos);
|
||||||
|
if (writeCount == data.Length)
|
||||||
|
return writeCount;
|
||||||
|
data.RemoveFromStart(writeCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Try!(Flush());
|
||||||
|
|
||||||
|
if ((mBuffer == null) || (data.Length > mBuffer.Count))
|
||||||
|
{
|
||||||
|
var result = TryWriteUnderlying(mPos, data);
|
||||||
|
if (result case .Ok(let len))
|
||||||
|
mPos += len;
|
||||||
|
writeCount += result;
|
||||||
|
return writeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBufferPos = mPos;
|
||||||
|
mWriteDirtyPos = mPos;
|
||||||
|
Internal.MemCpy(mBuffer.Ptr, data.Ptr, data.Length);
|
||||||
|
mPos += data.Length;
|
||||||
|
mBufferEnd = mPos;
|
||||||
|
mWriteDirtyEnd = mPos;
|
||||||
|
writeCount += data.Length;
|
||||||
|
return writeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Result<void> Flush()
|
||||||
|
{
|
||||||
|
if (mWriteDirtyPos >= 0)
|
||||||
|
{
|
||||||
|
Try!(TryWriteUnderlying(mWriteDirtyPos, .(mBuffer.Ptr + (mWriteDirtyPos - mBufferPos), (.)(mWriteDirtyEnd - mWriteDirtyPos))));
|
||||||
|
mWriteDirtyPos = -Int32.MinValue;
|
||||||
|
mWriteDirtyEnd = -Int32.MinValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Result<void> Close()
|
||||||
|
{
|
||||||
|
return Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -101,9 +101,9 @@ namespace System.IO
|
||||||
return .Ok(count);
|
return .Ok(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
public override Result<void> Close()
|
||||||
{
|
{
|
||||||
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveFromStart(int count)
|
public void RemoveFromStart(int count)
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace System.IO
|
||||||
|
|
||||||
public ~this()
|
public ~this()
|
||||||
{
|
{
|
||||||
Close();
|
Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result<void> Seek(int64 pos, SeekKind seekKind = .Absolute)
|
public override Result<void> Seek(int64 pos, SeekKind seekKind = .Absolute)
|
||||||
|
@ -52,7 +52,7 @@ namespace System.IO
|
||||||
return numBytesRead;
|
return numBytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<int> TryRead(Span<uint8> data, int timeoutMS)
|
public virtual Result<int> TryRead(Span<uint8> data, int timeoutMS)
|
||||||
{
|
{
|
||||||
Platform.BfpFileResult result = .Ok;
|
Platform.BfpFileResult result = .Ok;
|
||||||
int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, timeoutMS, &result);
|
int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, timeoutMS, &result);
|
||||||
|
@ -70,21 +70,28 @@ namespace System.IO
|
||||||
return numBytesWritten;
|
return numBytesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
public override Result<void> Close()
|
||||||
{
|
{
|
||||||
if (mBfpFile != null)
|
if (mBfpFile != null)
|
||||||
Platform.BfpFile_Release(mBfpFile);
|
Platform.BfpFile_Release(mBfpFile);
|
||||||
mBfpFile = null;
|
mBfpFile = null;
|
||||||
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Flush()
|
public override Result<void> Flush()
|
||||||
{
|
{
|
||||||
if (mBfpFile != null)
|
if (mBfpFile != null)
|
||||||
Platform.BfpFile_Flush(mBfpFile);
|
Platform.BfpFile_Flush(mBfpFile);
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Delete()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FileStream : FileStreamBase
|
class UnbufferedFileStream : FileStreamBase
|
||||||
{
|
{
|
||||||
FileAccess mFileAccess;
|
FileAccess mFileAccess;
|
||||||
|
|
||||||
|
@ -211,10 +218,228 @@ namespace System.IO
|
||||||
mFileAccess = access;
|
mFileAccess = access;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
public override Result<void> Close()
|
||||||
{
|
{
|
||||||
base.Close();
|
|
||||||
mFileAccess = default;
|
mFileAccess = default;
|
||||||
|
if (base.Close() case .Err)
|
||||||
|
return .Err;
|
||||||
|
return .Ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BufferedFileStream : BufferedStream
|
||||||
|
{
|
||||||
|
protected Platform.BfpFile* mBfpFile;
|
||||||
|
protected int64 mBfpFilePos;
|
||||||
|
FileAccess mFileAccess;
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ~this()
|
||||||
|
{
|
||||||
|
Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Delete()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(Platform.BfpFile* handle, FileAccess access, int32 bufferSize, bool isAsync)
|
||||||
|
{
|
||||||
|
mBfpFile = handle;
|
||||||
|
mFileAccess = access;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanRead
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mFileAccess.HasFlag(FileAccess.Read);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanWrite
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return mFileAccess.HasFlag(FileAccess.Write);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<void, FileOpenError> Create(StringView path, FileAccess access = .ReadWrite, FileShare share = .None, int bufferSize = 4096, FileOptions options = .None, SecurityAttributes* secAttrs = null)
|
||||||
|
{
|
||||||
|
return Open(path, FileMode.Create, access, share, bufferSize, options, secAttrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<void, FileOpenError> Open(StringView path, FileAccess access = .ReadWrite, FileShare share = .None, int bufferSize = 4096, FileOptions options = .None, SecurityAttributes* secAttrs = null)
|
||||||
|
{
|
||||||
|
return Open(path, FileMode.Open, access, share, bufferSize, options, secAttrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<void, FileOpenError> OpenStd(Platform.BfpFileStdKind stdKind)
|
||||||
|
{
|
||||||
|
Platform.BfpFileResult fileResult = .Ok;
|
||||||
|
mBfpFile = Platform.BfpFile_GetStd(stdKind, &fileResult);
|
||||||
|
mFileAccess = .ReadWrite;
|
||||||
|
|
||||||
|
if ((mBfpFile == null) || (fileResult != .Ok))
|
||||||
|
{
|
||||||
|
switch (fileResult)
|
||||||
|
{
|
||||||
|
case .ShareError:
|
||||||
|
return .Err(.SharingViolation);
|
||||||
|
case .NotFound:
|
||||||
|
return .Err(.NotFound);
|
||||||
|
default:
|
||||||
|
return .Err(.Unknown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<void, FileOpenError> Open(StringView path, FileMode mode, FileAccess access, FileShare share = .None, int bufferSize = 4096, FileOptions options = .None, SecurityAttributes* secAttrs = null)
|
||||||
|
{
|
||||||
|
Runtime.Assert(mBfpFile == null);
|
||||||
|
|
||||||
|
Platform.BfpFileCreateKind createKind = .CreateAlways;
|
||||||
|
Platform.BfpFileCreateFlags createFlags = .None;
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case .CreateNew:
|
||||||
|
createKind = .CreateIfNotExists;
|
||||||
|
case .Create:
|
||||||
|
createKind = .CreateAlways;
|
||||||
|
case .Open:
|
||||||
|
createKind = .OpenExisting;
|
||||||
|
case .OpenOrCreate:
|
||||||
|
createKind = .CreateAlways;
|
||||||
|
case .Truncate:
|
||||||
|
createKind = .CreateAlways;
|
||||||
|
createFlags |= .Truncate;
|
||||||
|
case .Append:
|
||||||
|
createKind = .CreateAlways;
|
||||||
|
createFlags |= .Append;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (access.HasFlag(.Read))
|
||||||
|
createFlags |= .Read;
|
||||||
|
if (access.HasFlag(.Write))
|
||||||
|
createFlags |= .Write;
|
||||||
|
|
||||||
|
if (share.HasFlag(.Read))
|
||||||
|
createFlags |= .ShareRead;
|
||||||
|
if (share.HasFlag(.Write))
|
||||||
|
createFlags |= .ShareWrite;
|
||||||
|
if (share.HasFlag(.Delete))
|
||||||
|
createFlags |= .ShareDelete;
|
||||||
|
|
||||||
|
Platform.BfpFileAttributes fileFlags = .Normal;
|
||||||
|
|
||||||
|
Platform.BfpFileResult fileResult = .Ok;
|
||||||
|
mBfpFile = Platform.BfpFile_Create(path.ToScopeCStr!(128), createKind, createFlags, fileFlags, &fileResult);
|
||||||
|
|
||||||
|
if ((mBfpFile == null) || (fileResult != .Ok))
|
||||||
|
{
|
||||||
|
switch (fileResult)
|
||||||
|
{
|
||||||
|
case .ShareError:
|
||||||
|
return .Err(.SharingViolation);
|
||||||
|
case .NotFound:
|
||||||
|
return .Err(.NotFound);
|
||||||
|
default:
|
||||||
|
return .Err(.Unknown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mFileAccess = access;
|
||||||
|
|
||||||
|
MakeBuffer(bufferSize);
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Attach(Platform.BfpFile* bfpFile, FileAccess access = .ReadWrite)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
mBfpFile = bfpFile;
|
||||||
|
mFileAccess = access;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Result<void> Close()
|
||||||
|
{
|
||||||
|
var hadError = Flush() case .Err;
|
||||||
|
if (mBfpFile != null)
|
||||||
|
Platform.BfpFile_Release(mBfpFile);
|
||||||
|
mBfpFile = null;
|
||||||
|
mFileAccess = default;
|
||||||
|
if (hadError)
|
||||||
|
return .Err;
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void UpdateLength()
|
||||||
|
{
|
||||||
|
mUnderlyingLength = Platform.BfpFile_GetFileSize(mBfpFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result<int> TryReadUnderlying(int64 pos, Span<uint8> data)
|
||||||
|
{
|
||||||
|
if (mBfpFilePos != pos)
|
||||||
|
{
|
||||||
|
int64 newPos = Platform.BfpFile_Seek(mBfpFile, pos, .Absolute);
|
||||||
|
if (newPos != pos)
|
||||||
|
return .Err;
|
||||||
|
mBfpFilePos = pos;
|
||||||
|
}
|
||||||
|
Platform.BfpFileResult result = .Ok;
|
||||||
|
int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, -1, &result);
|
||||||
|
if ((result != .Ok) && (result != .PartialData))
|
||||||
|
return .Err;
|
||||||
|
mBfpFilePos += numBytesRead;
|
||||||
|
return numBytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result<int> TryWriteUnderlying(int64 pos, Span<uint8> data)
|
||||||
|
{
|
||||||
|
if (mBfpFilePos != pos)
|
||||||
|
{
|
||||||
|
int64 newPos = Platform.BfpFile_Seek(mBfpFile, pos, .Absolute);
|
||||||
|
if (newPos != pos)
|
||||||
|
return .Err;
|
||||||
|
mBfpFilePos = pos;
|
||||||
|
}
|
||||||
|
Platform.BfpFileResult result = .Ok;
|
||||||
|
int numBytesRead = Platform.BfpFile_Write(mBfpFile, data.Ptr, data.Length, -1, &result);
|
||||||
|
if ((result != .Ok) && (result != .PartialData))
|
||||||
|
return .Err;
|
||||||
|
mBfpFilePos += numBytesRead;
|
||||||
|
return numBytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<int> TryRead(Span<uint8> data, int timeoutMS)
|
||||||
|
{
|
||||||
|
if (mBfpFilePos != mPos)
|
||||||
|
{
|
||||||
|
int64 newPos = Platform.BfpFile_Seek(mBfpFile, mPos, .Absolute);
|
||||||
|
if (newPos != mPos)
|
||||||
|
return .Err;
|
||||||
|
mBfpFilePos = mPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Platform.BfpFileResult result = .Ok;
|
||||||
|
int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, timeoutMS, &result);
|
||||||
|
if ((result != .Ok) && (result != .PartialData))
|
||||||
|
return .Err;
|
||||||
|
return numBytesRead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileStream : BufferedFileStream
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,9 +71,9 @@ namespace System.IO
|
||||||
return .Ok(count);
|
return .Ok(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
public override Result<void> Close()
|
||||||
{
|
{
|
||||||
|
return .Ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,9 +56,9 @@ namespace System.IO
|
||||||
return .Ok(data.Length);
|
return .Ok(data.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
public override Result<void> Close()
|
||||||
{
|
{
|
||||||
|
return .Ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace System.IO
|
||||||
|
|
||||||
public abstract Result<int> TryRead(Span<uint8> data);
|
public abstract Result<int> TryRead(Span<uint8> data);
|
||||||
public abstract Result<int> TryWrite(Span<uint8> data);
|
public abstract Result<int> TryWrite(Span<uint8> data);
|
||||||
public abstract void Close();
|
public abstract Result<void> Close();
|
||||||
|
|
||||||
//Read value from stream without changing position. Position won't change even if it returns .Err
|
//Read value from stream without changing position. Position won't change even if it returns .Err
|
||||||
public Result<T> Peek<T>() where T : struct
|
public Result<T> Peek<T>() where T : struct
|
||||||
|
@ -134,10 +134,16 @@ namespace System.IO
|
||||||
public Result<T> Read<T>() where T : struct
|
public Result<T> Read<T>() where T : struct
|
||||||
{
|
{
|
||||||
T val = ?;
|
T val = ?;
|
||||||
int size = Try!(TryRead(.((uint8*)&val, sizeof(T))));
|
var result = TryRead(.((uint8*)&val, sizeof(T)));
|
||||||
if (size != sizeof(T))
|
switch (result)
|
||||||
|
{
|
||||||
|
case .Ok(let size):
|
||||||
|
if (size != sizeof(T))
|
||||||
|
return .Err;
|
||||||
|
return .Ok(val);
|
||||||
|
case .Err:
|
||||||
return .Err;
|
return .Err;
|
||||||
return .Ok(val);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<void> Write<T>(T val) where T : struct
|
public Result<void> Write<T>(T val) where T : struct
|
||||||
|
@ -186,8 +192,9 @@ namespace System.IO
|
||||||
return .Ok;
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Flush()
|
public virtual Result<void> Flush()
|
||||||
{
|
{
|
||||||
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Align(int alignSize)
|
public void Align(int alignSize)
|
||||||
|
|
|
@ -157,9 +157,9 @@ namespace System.IO
|
||||||
return .Ok(count);
|
return .Ok(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
public override Result<void> Close()
|
||||||
{
|
{
|
||||||
|
return .Ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,14 +90,14 @@ namespace System.IO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
public override Result<void> Close()
|
||||||
{
|
{
|
||||||
mChildStream.Close();
|
return mChildStream.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Flush()
|
public override Result<void> Flush()
|
||||||
{
|
{
|
||||||
mChildStream.Flush();
|
return mChildStream.Flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,9 @@ namespace System
|
||||||
return .Ok(data.Length);
|
return .Ok(data.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
public override Result<void> Close()
|
||||||
{
|
{
|
||||||
|
return .Ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1451,6 +1451,9 @@ namespace System
|
||||||
[CLink, CallingConvention(.Stdcall)]
|
[CLink, CallingConvention(.Stdcall)]
|
||||||
public static extern Handle OpenFileMappingA(uint32 dwDesiredAccess, IntBool bInheritHandle, char8* lpName);
|
public static extern Handle OpenFileMappingA(uint32 dwDesiredAccess, IntBool bInheritHandle, char8* lpName);
|
||||||
|
|
||||||
|
[CLink, CallingConvention(.Stdcall)]
|
||||||
|
public static extern Handle CreateFileMappingA(Handle hFile, SecurityAttributes* securityAttrs, uint32 flProtect, uint32 dwMaximumSizeHigh, uint32 dwMaximumSizeLow, char8* lpName);
|
||||||
|
|
||||||
[CLink, CallingConvention(.Stdcall)]
|
[CLink, CallingConvention(.Stdcall)]
|
||||||
public static extern void* MapViewOfFile(Handle hFileMappingObject, uint32 dwDesiredAccess, uint32 dwFileOffsetHigh, uint32 dwFileOffsetLow, int dwNumberOfBytesToMap);
|
public static extern void* MapViewOfFile(Handle hFileMappingObject, uint32 dwDesiredAccess, uint32 dwFileOffsetHigh, uint32 dwFileOffsetLow, int dwNumberOfBytesToMap);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue