mirror of
https://github.com/beefytech/Beef.git
synced 2025-07-04 23:36:00 +02:00
Merge branch 'master' into bufstream-fixes
This commit is contained in:
commit
92738418eb
243 changed files with 19052 additions and 2933 deletions
|
@ -68,7 +68,7 @@ namespace System.IO
|
|||
|
||||
public override Result<int> TryRead(Span<uint8> data)
|
||||
{
|
||||
int spaceLeft = (.)(mBufferEnd - mPos);
|
||||
int64 spaceLeft = (.)(mBufferEnd - mPos);
|
||||
if (mPos < mBufferPos)
|
||||
spaceLeft = 0;
|
||||
if (data.Length <= spaceLeft)
|
||||
|
@ -83,19 +83,17 @@ namespace System.IO
|
|||
var data;
|
||||
if (spaceLeft > 0)
|
||||
{
|
||||
Internal.MemCpy(data.Ptr, mBuffer.Ptr + (mPos - mBufferPos), spaceLeft);
|
||||
Internal.MemCpy(data.Ptr, mBuffer.Ptr + (mPos - mBufferPos), (.)spaceLeft);
|
||||
mPos += spaceLeft;
|
||||
data.RemoveFromStart(spaceLeft);
|
||||
data.RemoveFromStart((.)spaceLeft);
|
||||
}
|
||||
|
||||
if (mWriteDirtyPos >= 0)
|
||||
Try!(Flush());
|
||||
Try!(Flush());
|
||||
|
||||
if ((mBuffer == null) || (data.Length > mBuffer.Count))
|
||||
{
|
||||
var result = TryReadUnderlying(mPos, data);
|
||||
if (result case .Ok(let len))
|
||||
mPos += len;
|
||||
let len = Try!(TryReadUnderlying(mPos, data));
|
||||
mPos += len;
|
||||
return (.)(mPos - readStart);
|
||||
}
|
||||
|
||||
|
@ -148,10 +146,9 @@ namespace System.IO
|
|||
|
||||
if ((mBuffer == null) || (data.Length > mBuffer.Count))
|
||||
{
|
||||
var result = TryWriteUnderlying(mPos, data);
|
||||
if (result case .Ok(let len))
|
||||
mPos += len;
|
||||
writeCount += result;
|
||||
let len = Try!(TryWriteUnderlying(mPos, data));
|
||||
mPos += len;
|
||||
writeCount += len;
|
||||
return writeCount;
|
||||
}
|
||||
|
||||
|
|
|
@ -240,7 +240,7 @@ namespace System.IO
|
|||
}
|
||||
}
|
||||
|
||||
struct FileEnumerator : IEnumerator<FileFindEntry>
|
||||
struct FileEnumerator : IEnumerator<FileFindEntry>, IDisposable
|
||||
{
|
||||
String mSearchStr;
|
||||
Platform.BfpFindFileData* mFindFileData;
|
||||
|
|
|
@ -15,6 +15,11 @@ namespace System.IO
|
|||
mOwnsData = true;
|
||||
}
|
||||
|
||||
public this(List<uint8> data)
|
||||
{
|
||||
mData = data;
|
||||
}
|
||||
|
||||
public uint8* Ptr
|
||||
{
|
||||
get
|
||||
|
@ -112,4 +117,100 @@ namespace System.IO
|
|||
mData.RemoveRange(0, count);
|
||||
}
|
||||
}
|
||||
|
||||
class DynMemStreamSequential : Stream
|
||||
{
|
||||
List<uint8> mData ~ { if (mOwnsData) delete _; };
|
||||
bool mOwnsData;
|
||||
|
||||
public this()
|
||||
{
|
||||
mData = new .();
|
||||
mOwnsData = true;
|
||||
}
|
||||
|
||||
public this(List<uint8> data)
|
||||
{
|
||||
mData = data;
|
||||
}
|
||||
|
||||
public uint8* Ptr
|
||||
{
|
||||
get
|
||||
{
|
||||
return mData.Ptr;
|
||||
}
|
||||
}
|
||||
|
||||
public Span<uint8> Content
|
||||
{
|
||||
get
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
}
|
||||
|
||||
public override int64 Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return mData.Count;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
Runtime.FatalError();
|
||||
}
|
||||
}
|
||||
|
||||
public override int64 Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return mData.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public List<uint8> TakeOwnership()
|
||||
{
|
||||
Debug.Assert(mOwnsData);
|
||||
mOwnsData = false;
|
||||
return mData;
|
||||
}
|
||||
|
||||
public override Result<int> TryRead(Span<uint8> data)
|
||||
{
|
||||
return .Err;
|
||||
}
|
||||
|
||||
public override Result<int> TryWrite(Span<uint8> data)
|
||||
{
|
||||
let count = data.Length;
|
||||
if (count == 0)
|
||||
return .Ok(0);
|
||||
Internal.MemCpy(mData.GrowUnitialized(count), data.Ptr, count);
|
||||
return .Ok(count);
|
||||
}
|
||||
|
||||
public override Result<void> Close()
|
||||
{
|
||||
return .Ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace System.IO
|
|||
case FileReadError(FileReadError);
|
||||
}
|
||||
|
||||
class File
|
||||
static class File
|
||||
{
|
||||
public static Result<void, FileError> ReadAll(StringView path, List<uint8> outData)
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ namespace System.IO
|
|||
|
||||
public static Result<void> WriteAll(StringView path, Span<uint8> data, bool doAppend = false)
|
||||
{
|
||||
FileStream fs = scope FileStream();
|
||||
UnbufferedFileStream fs = scope UnbufferedFileStream();
|
||||
var result = fs.Open(path, doAppend ? .Append : .Create, .Write);
|
||||
if (result case .Err)
|
||||
return .Err;
|
||||
|
@ -76,7 +76,7 @@ namespace System.IO
|
|||
|
||||
public static Result<void> WriteAllText(StringView path, StringView text, bool doAppend = false)
|
||||
{
|
||||
FileStream fs = scope FileStream();
|
||||
UnbufferedFileStream fs = scope UnbufferedFileStream();
|
||||
var result = fs.Open(path, doAppend ? .Append : .Create, .Write);
|
||||
if (result case .Err)
|
||||
return .Err;
|
||||
|
@ -87,7 +87,7 @@ namespace System.IO
|
|||
|
||||
public static Result<void> WriteAllText(StringView path, StringView text, Encoding encoding)
|
||||
{
|
||||
FileStream fs = scope FileStream();
|
||||
UnbufferedFileStream fs = scope UnbufferedFileStream();
|
||||
|
||||
int len = encoding.GetEncodedSize(text);
|
||||
uint8* data = new uint8[len]*;
|
||||
|
|
|
@ -17,16 +17,16 @@ namespace System.IO
|
|||
/// Opens an existing file. Fails if the file does not exist.
|
||||
Open = 3,
|
||||
|
||||
// Opens the file if it exists. Otherwise, creates a new file.
|
||||
/// Opens the file if it exists. Otherwise, creates a new file.
|
||||
OpenOrCreate = 4,
|
||||
|
||||
// Opens an existing file. Once opened, the file is truncated so that its
|
||||
// size is zero bytes. The calling process must open the file with at least
|
||||
// WRITE access. Fails if the file does not exist.
|
||||
/// Opens an existing file. Once opened, the file is truncated so that its
|
||||
/// size is zero bytes. The calling process must open the file with at least
|
||||
/// WRITE access. Fails if the file does not exist.
|
||||
Truncate = 5,
|
||||
|
||||
// Opens the file if it exists and seeks to the end. Otherwise,
|
||||
// creates a new file.
|
||||
/// Opens the file if it exists and seeks to the end. Otherwise,
|
||||
/// creates a new file.
|
||||
Append = 6,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,16 @@ namespace System.IO
|
|||
}
|
||||
}
|
||||
|
||||
public int Handle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mBfpFile == null)
|
||||
return 0;
|
||||
return Platform.BfpFile_GetSystemHandle(mBfpFile);
|
||||
}
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
Delete();
|
||||
|
@ -165,12 +175,13 @@ namespace System.IO
|
|||
createKind = .CreateIfNotExists;
|
||||
case .Create:
|
||||
createKind = .CreateAlways;
|
||||
createFlags |= .Truncate;
|
||||
case .Open:
|
||||
createKind = .OpenExisting;
|
||||
case .OpenOrCreate:
|
||||
createKind = .CreateAlways;
|
||||
createKind = .OpenAlways;
|
||||
case .Truncate:
|
||||
createKind = .CreateAlways;
|
||||
createKind = .OpenExisting;
|
||||
createFlags |= .Truncate;
|
||||
case .Append:
|
||||
createKind = .CreateAlways;
|
||||
|
@ -225,6 +236,32 @@ namespace System.IO
|
|||
return .Err;
|
||||
return .Ok;
|
||||
}
|
||||
|
||||
public override Result<void> SetLength(int64 length)
|
||||
{
|
||||
int64 pos = Position;
|
||||
|
||||
if (pos != length)
|
||||
Seek(length);
|
||||
|
||||
Platform.BfpFileResult result = .Ok;
|
||||
Platform.BfpFile_Truncate(mBfpFile, &result);
|
||||
if (result != .Ok)
|
||||
{
|
||||
Seek(pos);
|
||||
return .Err;
|
||||
}
|
||||
|
||||
if (pos != length)
|
||||
{
|
||||
if (pos < length)
|
||||
Seek(pos);
|
||||
else
|
||||
Seek(0, .FromEnd);
|
||||
}
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
}
|
||||
|
||||
class BufferedFileStream : BufferedStream
|
||||
|
@ -233,6 +270,32 @@ namespace System.IO
|
|||
protected int64 mBfpFilePos;
|
||||
FileAccess mFileAccess;
|
||||
|
||||
public int Handle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mBfpFile == null)
|
||||
return 0;
|
||||
return Platform.BfpFile_GetSystemHandle(mBfpFile);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFileAccess.HasFlag(FileAccess.Read);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFileAccess.HasFlag(FileAccess.Write);
|
||||
}
|
||||
}
|
||||
|
||||
public this()
|
||||
{
|
||||
|
||||
|
@ -254,22 +317,6 @@ namespace System.IO
|
|||
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);
|
||||
|
@ -317,7 +364,7 @@ namespace System.IO
|
|||
case .Open:
|
||||
createKind = .OpenExisting;
|
||||
case .OpenOrCreate:
|
||||
createKind = .CreateAlways;
|
||||
createKind = .OpenAlways;
|
||||
case .Truncate:
|
||||
createKind = .CreateAlways;
|
||||
createFlags |= .Truncate;
|
||||
|
@ -386,15 +433,20 @@ namespace System.IO
|
|||
mUnderlyingLength = Platform.BfpFile_GetFileSize(mBfpFile);
|
||||
}
|
||||
|
||||
protected Result<void> SeekUnderlying(int64 offset, Platform.BfpFileSeekKind seekKind = .Absolute)
|
||||
{
|
||||
int64 newPos = Platform.BfpFile_Seek(mBfpFile, offset, seekKind);
|
||||
Result<void> result = ((seekKind == .Absolute) && (newPos != offset)) ? .Err : .Ok;
|
||||
if (result case .Ok)
|
||||
mBfpFilePos = newPos;
|
||||
return result;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
Try!(SeekUnderlying(pos));
|
||||
|
||||
Platform.BfpFileResult result = .Ok;
|
||||
int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, -1, &result);
|
||||
if ((result != .Ok) && (result != .PartialData))
|
||||
|
@ -406,12 +458,8 @@ namespace System.IO
|
|||
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;
|
||||
}
|
||||
Try!(SeekUnderlying(pos));
|
||||
|
||||
Platform.BfpFileResult result = .Ok;
|
||||
int numBytesRead = Platform.BfpFile_Write(mBfpFile, data.Ptr, data.Length, -1, &result);
|
||||
if ((result != .Ok) && (result != .PartialData))
|
||||
|
@ -423,12 +471,7 @@ namespace System.IO
|
|||
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;
|
||||
}
|
||||
Try!(SeekUnderlying(mPos));
|
||||
|
||||
Platform.BfpFileResult result = .Ok;
|
||||
int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, timeoutMS, &result);
|
||||
|
@ -436,6 +479,40 @@ namespace System.IO
|
|||
return .Err;
|
||||
return numBytesRead;
|
||||
}
|
||||
|
||||
public override Result<void> SetLength(int64 length)
|
||||
{
|
||||
Try!(Flush());
|
||||
|
||||
int64 pos = Position;
|
||||
|
||||
if (pos != length || pos != mBfpFilePos)
|
||||
{
|
||||
Try!(SeekUnderlying(length));
|
||||
mPos = length;
|
||||
}
|
||||
|
||||
Platform.BfpFileResult result = .Ok;
|
||||
Platform.BfpFile_Truncate(mBfpFile, &result);
|
||||
if (result != .Ok)
|
||||
{
|
||||
Try!(SeekUnderlying(pos));
|
||||
return .Err;
|
||||
}
|
||||
|
||||
mUnderlyingLength = length;
|
||||
mPos = Math.Min(pos, Length);
|
||||
|
||||
if (pos != length)
|
||||
{
|
||||
if (pos < length)
|
||||
Try!(SeekUnderlying(pos));
|
||||
else
|
||||
Try!(SeekUnderlying(0, .FromEnd));
|
||||
}
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
}
|
||||
|
||||
class FileStream : BufferedFileStream
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace System.IO
|
|||
{
|
||||
class MemoryStream : Stream
|
||||
{
|
||||
List<uint8> mMemory = new List<uint8>() ~ delete _;
|
||||
List<uint8> mMemory ~ delete _;
|
||||
int mPosition = 0;
|
||||
|
||||
public override int64 Position
|
||||
|
@ -44,6 +44,16 @@ namespace System.IO
|
|||
}
|
||||
}
|
||||
|
||||
public this()
|
||||
{
|
||||
mMemory = new List<uint8>();
|
||||
}
|
||||
|
||||
public this(List<uint8> memory)
|
||||
{
|
||||
mMemory = memory;
|
||||
}
|
||||
|
||||
public override Result<int> TryRead(Span<uint8> data)
|
||||
{
|
||||
let count = data.Length;
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace System.IO
|
|||
public const char8 DirectorySeparatorChar = '/';
|
||||
#endif //BF_PLATFORM_WINDOWS
|
||||
|
||||
// Platform specific alternate directory separator char8acter.
|
||||
// Platform specific alternate directory separator character.
|
||||
// This is backslash ('\') on Unix, and slash ('/') on Windows
|
||||
// and MacOS.
|
||||
//
|
||||
|
@ -25,7 +25,7 @@ namespace System.IO
|
|||
public const char8 AltDirectorySeparatorChar = '\\';
|
||||
#endif //BF_PLATFORM_WINDOWS
|
||||
|
||||
// Platform specific volume separator char8acter. This is colon (':')
|
||||
// Platform specific volume separator character. This is colon (':')
|
||||
// on Windows and MacOS, and slash ('/') on Unix. This is mostly
|
||||
// useful for parsing paths like "c:\windows" or "MacVolume:System Folder".
|
||||
//
|
||||
|
@ -37,7 +37,7 @@ namespace System.IO
|
|||
|
||||
// Make this public sometime.
|
||||
// The max total path is 260, and the max individual component length is 255.
|
||||
// For example, D:\<256 char8 file name> isn't legal, even though it's under 260 char8s.
|
||||
// For example, D:\<256 char file name> isn't legal, even though it's under 260 chars.
|
||||
protected const int32 MaxPath = 260;
|
||||
private const int32 MaxDirectoryLength = 255;
|
||||
|
||||
|
@ -297,7 +297,7 @@ namespace System.IO
|
|||
return .Ok;
|
||||
}
|
||||
|
||||
public static void InternalCombine(String target, params String[] components)
|
||||
public static void InternalCombine(String target, params StringView[] components)
|
||||
{
|
||||
for (var component in components)
|
||||
{
|
||||
|
|
|
@ -97,25 +97,32 @@ namespace System.IO
|
|||
}
|
||||
}
|
||||
|
||||
//Read sized string from stream
|
||||
public Result<void> ReadStrSized32(int64 size, String output)
|
||||
/// Read sized string from stream
|
||||
public Result<void> ReadStrSized32(int size, String output)
|
||||
{
|
||||
if (size <= 0)
|
||||
if (size < 0)
|
||||
return .Err;
|
||||
|
||||
for (int64 i = 0; i < size; i++)
|
||||
int prevLen = output.Length;
|
||||
char8* buf = output.PrepareBuffer(size);
|
||||
switch (TryRead(.((uint8*)buf, size)))
|
||||
{
|
||||
Result<char8> char = Read<char8>();
|
||||
if (char == .Err)
|
||||
return .Err;
|
||||
|
||||
output.Append(char);
|
||||
case .Ok(let readLen):
|
||||
if (readLen < size)
|
||||
output.Length = prevLen + readLen;
|
||||
return .Ok;
|
||||
case .Err:
|
||||
return .Err;
|
||||
}
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
|
||||
//Reads null terminated ASCII string from the stream. Null terminator is read from stream but isn't appended to output string
|
||||
public Result<void> ReadStrSized32(String output)
|
||||
{
|
||||
int size = Try!(Read<int32>());
|
||||
return ReadStrSized32(size, output);
|
||||
}
|
||||
|
||||
/// Reads null terminated ASCII string from the stream. Null terminator is read from stream but isn't appended to output string
|
||||
public Result<void> ReadStrC(String output)
|
||||
{
|
||||
Result<char8> char0;
|
||||
|
@ -197,6 +204,11 @@ namespace System.IO
|
|||
return .Ok;
|
||||
}
|
||||
|
||||
public virtual Result<void> SetLength(int64 length)
|
||||
{
|
||||
return .Err;
|
||||
}
|
||||
|
||||
public void Align(int alignSize)
|
||||
{
|
||||
int64 pos = Length;
|
||||
|
|
|
@ -256,7 +256,7 @@ namespace System.IO
|
|||
{
|
||||
char8 ch = tmpCharBuffer[i];
|
||||
|
||||
// Note the following common line feed char8s:
|
||||
// Note the following common line feed chars:
|
||||
// \n - UNIX \r\n - DOS \r - Mac
|
||||
if (ch == '\r' || ch == '\n')
|
||||
{
|
||||
|
@ -481,7 +481,7 @@ namespace System.IO
|
|||
}
|
||||
while (mCharLen == 0);
|
||||
|
||||
//Console.WriteLine("ReadBuffer called. char8s: "+char8Len);
|
||||
//Console.WriteLine("ReadBuffer called. chars: "+char8Len);
|
||||
return mCharLen;
|
||||
}
|
||||
|
||||
|
@ -522,7 +522,7 @@ namespace System.IO
|
|||
repeat
|
||||
{
|
||||
char8 ch = mCharBuffer[i];
|
||||
// Note the following common line feed char8s:
|
||||
// Note the following common line feed chars:
|
||||
// \n - UNIX \r\n - DOS \r - Mac
|
||||
if (ch == '\r' || ch == '\n')
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue