1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-18 16:10:26 +02:00

Static init priority changes, Platform hooking

This commit is contained in:
Brian Fiete 2025-01-17 10:17:19 -08:00
parent e478462487
commit 1de07d0ee4
13 changed files with 328 additions and 87 deletions

View file

@ -1,6 +1,6 @@
namespace System.FFI namespace System.FFI
{ {
[CRepr, StaticInitPriority(100)] [CRepr, StaticInitPriority(200)]
struct FFIType struct FFIType
{ {
public enum TypeKind : uint16 public enum TypeKind : uint16

View file

@ -135,7 +135,7 @@ namespace System.IO
bfpFlags |= .Directories; bfpFlags |= .Directories;
if (flags.HasFlag(.Files)) if (flags.HasFlag(.Files))
bfpFlags |= .Files; bfpFlags |= .Files;
let findFileData = Platform.BfpFindFileData_FindFirstFile(useStr, bfpFlags, null); let findFileData = Platform.Hook.BfpFindFileData_FindFirstFile(useStr, bfpFlags, null);
return FileEnumerator(useStr, findFileData); return FileEnumerator(useStr, findFileData);
} }
@ -206,7 +206,7 @@ namespace System.IO
{ {
get get
{ {
return Platform.BfpFindFileData_GetFileAttributes(mFindFileData).HasFlag(.Directory); return Platform.Hook.BfpFindFileData_GetFileAttributes(mFindFileData).HasFlag(.Directory);
} }
} }
@ -214,7 +214,7 @@ namespace System.IO
{ {
Platform.GetStrHelper(outFileName, scope (outPtr, outSize, outResult) => Platform.GetStrHelper(outFileName, scope (outPtr, outSize, outResult) =>
{ {
Platform.BfpFindFileData_GetFileName(mFindFileData, outPtr, outSize, (Platform.BfpFileResult*)outResult); Platform.Hook.BfpFindFileData_GetFileName(mFindFileData, outPtr, outSize, (Platform.BfpFileResult*)outResult);
}); });
} }
@ -228,43 +228,45 @@ namespace System.IO
public DateTime GetLastWriteTime() public DateTime GetLastWriteTime()
{ {
return DateTime.FromFileTime((int64)Platform.BfpFindFileData_GetTime_LastWrite(mFindFileData)); return DateTime.FromFileTime((int64)Platform.Hook.BfpFindFileData_GetTime_LastWrite(mFindFileData));
} }
public DateTime GetLastWriteTimeUtc() public DateTime GetLastWriteTimeUtc()
{ {
return DateTime.FromFileTimeUtc((int64)Platform.BfpFindFileData_GetTime_LastWrite(mFindFileData)); return DateTime.FromFileTimeUtc((int64)Platform.Hook.BfpFindFileData_GetTime_LastWrite(mFindFileData));
} }
public DateTime GetCreatedTime() public DateTime GetCreatedTime()
{ {
return DateTime.FromFileTime((int64)Platform.BfpFindFileData_GetTime_Created(mFindFileData)); return DateTime.FromFileTime((int64)Platform.Hook.BfpFindFileData_GetTime_Created(mFindFileData));
} }
public DateTime GetCreatedTimeUtc() public DateTime GetCreatedTimeUtc()
{ {
return DateTime.FromFileTimeUtc((int64)Platform.BfpFindFileData_GetTime_Created(mFindFileData)); return DateTime.FromFileTimeUtc((int64)Platform.Hook.BfpFindFileData_GetTime_Created(mFindFileData));
} }
public DateTime GetAccessedTime() public DateTime GetAccessedTime()
{ {
return DateTime.FromFileTime((int64)Platform.BfpFindFileData_GetTime_Access(mFindFileData)); return DateTime.FromFileTime((int64)Platform.Hook.BfpFindFileData_GetTime_Access(mFindFileData));
} }
public DateTime GetAccessedTimeUtc() public DateTime GetAccessedTimeUtc()
{ {
return DateTime.FromFileTimeUtc((int64)Platform.BfpFindFileData_GetTime_Access(mFindFileData)); return DateTime.FromFileTimeUtc((int64)Platform.Hook.BfpFindFileData_GetTime_Access(mFindFileData));
} }
public int64 GetFileSize() public int64 GetFileSize()
{ {
return Platform.BfpFindFileData_GetFileSize(mFindFileData); return Platform.Hook.BfpFindFileData_GetFileSize(mFindFileData);
} }
public Platform.BfpFileAttributes GetFileAttributes() public Platform.BfpFileAttributes GetFileAttributes()
{ {
return Platform.BfpFindFileData_GetFileAttributes(mFindFileData); return Platform.Hook.BfpFindFileData_GetFileAttributes(mFindFileData);
} }
public static bool operator implicit (Self self) => self.mFindFileData != null;
} }
struct FileEnumerator : IEnumerator<FileFindEntry>, IDisposable struct FileEnumerator : IEnumerator<FileFindEntry>, IDisposable
@ -292,7 +294,7 @@ namespace System.IO
{ {
delete mSearchStr; delete mSearchStr;
if (mFindFileData != null) if (mFindFileData != null)
Platform.BfpFindFileData_Release(mFindFileData); Platform.Hook.BfpFindFileData_Release(mFindFileData);
} }
public bool MoveNext() mut public bool MoveNext() mut
@ -301,7 +303,7 @@ namespace System.IO
if (mIdx == 0) if (mIdx == 0)
return mFindFileData != null; return mFindFileData != null;
return Platform.BfpFindFileData_FindNextFile(mFindFileData); return Platform.Hook.BfpFindFileData_FindNextFile(mFindFileData);
} }
public Result<FileFindEntry> GetNext() mut public Result<FileFindEntry> GetNext() mut

View file

@ -141,13 +141,13 @@ namespace System.IO
public static bool Exists(StringView fileName) public static bool Exists(StringView fileName)
{ {
return Platform.BfpFile_Exists(fileName.ToScopeCStr!()); return Platform.Hook.BfpFile_Exists(fileName.ToScopeCStr!());
} }
public static Result<void, Platform.BfpFileResult> Delete(StringView fileName) public static Result<void, Platform.BfpFileResult> Delete(StringView fileName)
{ {
Platform.BfpFileResult result = default; Platform.BfpFileResult result = default;
Platform.BfpFile_Delete(fileName.ToScopeCStr!(), &result); Platform.Hook.BfpFile_Delete(fileName.ToScopeCStr!(), &result);
if ((result != .Ok) && (result != .NotFound)) if ((result != .Ok) && (result != .NotFound))
return .Err(result); return .Err(result);
return .Ok; return .Ok;
@ -156,7 +156,7 @@ namespace System.IO
public static Result<void, Platform.BfpFileResult> Move(StringView fromPath, StringView toPath) public static Result<void, Platform.BfpFileResult> Move(StringView fromPath, StringView toPath)
{ {
Platform.BfpFileResult result = default; Platform.BfpFileResult result = default;
Platform.BfpFile_Rename(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), &result); Platform.Hook.BfpFile_Rename(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), &result);
if (result != .Ok) if (result != .Ok)
return .Err(result); return .Err(result);
return .Ok; return .Ok;
@ -165,7 +165,7 @@ namespace System.IO
public static Result<void, Platform.BfpFileResult> Copy(StringView fromPath, StringView toPath) public static Result<void, Platform.BfpFileResult> Copy(StringView fromPath, StringView toPath)
{ {
Platform.BfpFileResult result = default; Platform.BfpFileResult result = default;
Platform.BfpFile_Copy(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), .Always, &result); Platform.Hook.BfpFile_Copy(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), .Always, &result);
if (result != .Ok) if (result != .Ok)
return .Err(result); return .Err(result);
return .Ok; return .Ok;
@ -174,7 +174,7 @@ namespace System.IO
public static Result<void, Platform.BfpFileResult> CopyIfNewer(StringView fromPath, StringView toPath) public static Result<void, Platform.BfpFileResult> CopyIfNewer(StringView fromPath, StringView toPath)
{ {
Platform.BfpFileResult result = default; Platform.BfpFileResult result = default;
Platform.BfpFile_Copy(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), .IfNewer, &result); Platform.Hook.BfpFile_Copy(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), .IfNewer, &result);
if (result != .Ok) if (result != .Ok)
return .Err(result); return .Err(result);
return .Ok; return .Ok;
@ -183,7 +183,7 @@ namespace System.IO
public static Result<void, Platform.BfpFileResult> Copy(StringView fromPath, StringView toPath, bool overwrite) public static Result<void, Platform.BfpFileResult> Copy(StringView fromPath, StringView toPath, bool overwrite)
{ {
Platform.BfpFileResult result = default; Platform.BfpFileResult result = default;
Platform.BfpFile_Copy(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), overwrite ? .Always : .IfNotExists, &result); Platform.Hook.BfpFile_Copy(fromPath.ToScopeCStr!(), toPath.ToScopeCStr!(), overwrite ? .Always : .IfNotExists, &result);
if (result != .Ok) if (result != .Ok)
return .Err(result); return .Err(result);
return .Ok; return .Ok;
@ -192,7 +192,7 @@ namespace System.IO
public static Result<void, Platform.BfpFileResult> SetAttributes(StringView path, FileAttributes attr) public static Result<void, Platform.BfpFileResult> SetAttributes(StringView path, FileAttributes attr)
{ {
Platform.BfpFileResult result = default; Platform.BfpFileResult result = default;
Platform.BfpFile_SetAttributes(path.ToScopeCStr!(), (Platform.BfpFileAttributes)attr, &result); Platform.Hook.BfpFile_SetAttributes(path.ToScopeCStr!(), (Platform.BfpFileAttributes)attr, &result);
if (result != .Ok) if (result != .Ok)
return .Err(result); return .Err(result);
return .Ok; return .Ok;
@ -200,12 +200,47 @@ namespace System.IO
public static Result<DateTime> GetLastWriteTime(StringView fullPath) public static Result<DateTime> GetLastWriteTime(StringView fullPath)
{ {
return DateTime.FromFileTime((int64)Platform.BfpFile_GetTime_LastWrite(fullPath.ToScopeCStr!())); return DateTime.FromFileTime((int64)Platform.Hook.BfpFile_GetTime_LastWrite(fullPath.ToScopeCStr!()));
} }
public static Result<DateTime> GetLastWriteTimeUtc(StringView fullPath) public static Result<DateTime> GetLastWriteTimeUtc(StringView fullPath)
{ {
return DateTime.FromFileTimeUtc((int64)Platform.BfpFile_GetTime_LastWrite(fullPath.ToScopeCStr!())); return DateTime.FromFileTimeUtc((int64)Platform.Hook.BfpFile_GetTime_LastWrite(fullPath.ToScopeCStr!()));
} }
} }
class FileInfo
{
FileFindEntry mFileFindEntry;
public this(StringView path)
{
let findFileData = Platform.Hook.BfpFindFileData_FindFirstFile(path.ToScopeCStr!(), .Files, null);
if (findFileData == null)
return;
mFileFindEntry = .(new .(path), findFileData);
}
public ~this()
{
if (mFileFindEntry.[Friend]mSearchStr != null)
{
delete mFileFindEntry.[Friend]mSearchStr;
Platform.Hook.BfpFindFileData_Release(mFileFindEntry.[Friend]mFindFileData);
}
}
public bool Exists => mFileFindEntry;
public bool IsDirectory => mFileFindEntry ? mFileFindEntry.IsDirectory : default;
public void GetFileName(String outFileName) { if (mFileFindEntry) mFileFindEntry.GetFileName(outFileName); }
public void GetFilePath(String outPath) { if (mFileFindEntry) mFileFindEntry.GetFilePath(outPath); }
public DateTime GetLastWriteTime() => mFileFindEntry ? mFileFindEntry.GetLastWriteTime() : default;
public DateTime GetLastWriteTimeUtc() => mFileFindEntry ? mFileFindEntry.GetLastWriteTimeUtc() : default;
public DateTime GetCreatedTime() => mFileFindEntry ? mFileFindEntry.GetCreatedTime() : default;
public DateTime GetCreatedTimeUtc() => mFileFindEntry ? mFileFindEntry.GetCreatedTimeUtc() : default;
public DateTime GetAccessedTime() => mFileFindEntry ? mFileFindEntry.GetAccessedTime() : default;
public DateTime GetAccessedTimeUtc() => mFileFindEntry ? mFileFindEntry.GetAccessedTimeUtc() : default;
public int64 GetFileSize() => mFileFindEntry ? mFileFindEntry.GetFileSize() : default;
public Platform.BfpFileAttributes GetFileAttributes() => mFileFindEntry ? mFileFindEntry.GetFileAttributes() : default;
}
} }

View file

@ -12,12 +12,12 @@ namespace System.IO
{ {
get get
{ {
return Platform.BfpFile_Seek(mBfpFile, 0, .Relative); return Platform.Hook.BfpFile_Seek(mBfpFile, 0, .Relative);
} }
set set
{ {
Platform.BfpFile_Seek(mBfpFile, value, .Absolute); Platform.Hook.BfpFile_Seek(mBfpFile, value, .Absolute);
} }
} }
@ -25,7 +25,7 @@ namespace System.IO
{ {
get get
{ {
return Platform.BfpFile_GetFileSize(mBfpFile); return Platform.Hook.BfpFile_GetFileSize(mBfpFile);
} }
} }
@ -35,7 +35,7 @@ namespace System.IO
{ {
if (mBfpFile == null) if (mBfpFile == null)
return 0; return 0;
return Platform.BfpFile_GetSystemHandle(mBfpFile); return Platform.Hook.BfpFile_GetSystemHandle(mBfpFile);
} }
} }
@ -46,7 +46,7 @@ namespace System.IO
public override Result<void> Seek(int64 pos, SeekKind seekKind = .Absolute) public override Result<void> Seek(int64 pos, SeekKind seekKind = .Absolute)
{ {
int64 newPos = Platform.BfpFile_Seek(mBfpFile, pos, (Platform.BfpFileSeekKind)seekKind); int64 newPos = Platform.Hook.BfpFile_Seek(mBfpFile, pos, (Platform.BfpFileSeekKind)seekKind);
// Ensure position is what was requested // Ensure position is what was requested
if ((seekKind == .Absolute) && (newPos != pos)) if ((seekKind == .Absolute) && (newPos != pos))
return .Err; return .Err;
@ -56,7 +56,7 @@ namespace System.IO
public override Result<int> TryRead(Span<uint8> data) public override Result<int> TryRead(Span<uint8> data)
{ {
Platform.BfpFileResult result = .Ok; Platform.BfpFileResult result = .Ok;
int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, -1, &result); int numBytesRead = Platform.Hook.BfpFile_Read(mBfpFile, data.Ptr, data.Length, -1, &result);
if ((result != .Ok) && (result != .PartialData)) if ((result != .Ok) && (result != .PartialData))
return .Err; return .Err;
return numBytesRead; return numBytesRead;
@ -65,7 +65,7 @@ namespace System.IO
public override Result<int, FileError> TryRead(Span<uint8> data, int timeoutMS) public override Result<int, FileError> 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.Hook.BfpFile_Read(mBfpFile, data.Ptr, data.Length, timeoutMS, &result);
if ((result != .Ok) && (result != .PartialData)) if ((result != .Ok) && (result != .PartialData))
{ {
switch (result) switch (result)
@ -84,7 +84,7 @@ namespace System.IO
public override Result<int> TryWrite(Span<uint8> data) public override Result<int> TryWrite(Span<uint8> data)
{ {
Platform.BfpFileResult result = .Ok; Platform.BfpFileResult result = .Ok;
int numBytesWritten = Platform.BfpFile_Write(mBfpFile, data.Ptr, data.Length, -1, &result); int numBytesWritten = Platform.Hook.BfpFile_Write(mBfpFile, data.Ptr, data.Length, -1, &result);
if ((result != .Ok) && (result != .PartialData)) if ((result != .Ok) && (result != .PartialData))
return .Err; return .Err;
return numBytesWritten; return numBytesWritten;
@ -93,7 +93,7 @@ namespace System.IO
public override Result<void> Close() public override Result<void> Close()
{ {
if (mBfpFile != null) if (mBfpFile != null)
Platform.BfpFile_Release(mBfpFile); Platform.Hook.BfpFile_Release(mBfpFile);
mBfpFile = null; mBfpFile = null;
return .Ok; return .Ok;
} }
@ -101,7 +101,7 @@ namespace System.IO
public override Result<void> Flush() public override Result<void> Flush()
{ {
if (mBfpFile != null) if (mBfpFile != null)
Platform.BfpFile_Flush(mBfpFile); Platform.Hook.BfpFile_Flush(mBfpFile);
return .Ok; return .Ok;
} }
@ -159,7 +159,7 @@ namespace System.IO
public Result<void, FileOpenError> OpenStd(Platform.BfpFileStdKind stdKind) public Result<void, FileOpenError> OpenStd(Platform.BfpFileStdKind stdKind)
{ {
Platform.BfpFileResult fileResult = .Ok; Platform.BfpFileResult fileResult = .Ok;
mBfpFile = Platform.BfpFile_GetStd(stdKind, &fileResult); mBfpFile = Platform.Hook.BfpFile_GetStd(stdKind, &fileResult);
mFileAccess = .ReadWrite; mFileAccess = .ReadWrite;
if ((mBfpFile == null) || (fileResult != .Ok)) if ((mBfpFile == null) || (fileResult != .Ok))
@ -218,7 +218,7 @@ namespace System.IO
Platform.BfpFileAttributes fileFlags = .Normal; Platform.BfpFileAttributes fileFlags = .Normal;
Platform.BfpFileResult fileResult = .Ok; Platform.BfpFileResult fileResult = .Ok;
mBfpFile = Platform.BfpFile_Create(path.ToScopeCStr!(128), createKind, createFlags, fileFlags, &fileResult); mBfpFile = Platform.Hook.BfpFile_Create(path.ToScopeCStr!(128), createKind, createFlags, fileFlags, &fileResult);
if ((mBfpFile == null) || (fileResult != .Ok)) if ((mBfpFile == null) || (fileResult != .Ok))
{ {
@ -261,7 +261,7 @@ namespace System.IO
Seek(length); Seek(length);
Platform.BfpFileResult result = .Ok; Platform.BfpFileResult result = .Ok;
Platform.BfpFile_Truncate(mBfpFile, &result); Platform.Hook.BfpFile_Truncate(mBfpFile, &result);
if (result != .Ok) if (result != .Ok)
{ {
Seek(pos); Seek(pos);
@ -297,7 +297,7 @@ namespace System.IO
{ {
if (mBfpFile == null) if (mBfpFile == null)
return 0; return 0;
return Platform.BfpFile_GetSystemHandle(mBfpFile); return Platform.Hook.BfpFile_GetSystemHandle(mBfpFile);
} }
} }
@ -321,7 +321,7 @@ namespace System.IO
{ {
set set
{ {
// Matches the behavior of Platform.BfpFile_Seek(mBfpFile, value, .Absolute); // Matches the behavior of Platform.Hook.BfpFile_Seek(mBfpFile, value, .Absolute);
mPos = Math.Max(value, 0); mPos = Math.Max(value, 0);
} }
} }
@ -355,7 +355,7 @@ namespace System.IO
public Result<void, FileOpenError> OpenStd(Platform.BfpFileStdKind stdKind) public Result<void, FileOpenError> OpenStd(Platform.BfpFileStdKind stdKind)
{ {
Platform.BfpFileResult fileResult = .Ok; Platform.BfpFileResult fileResult = .Ok;
mBfpFile = Platform.BfpFile_GetStd(stdKind, &fileResult); mBfpFile = Platform.Hook.BfpFile_GetStd(stdKind, &fileResult);
mFileAccess = .ReadWrite; mFileAccess = .ReadWrite;
if ((mBfpFile == null) || (fileResult != .Ok)) if ((mBfpFile == null) || (fileResult != .Ok))
@ -413,7 +413,7 @@ namespace System.IO
Platform.BfpFileAttributes fileFlags = .Normal; Platform.BfpFileAttributes fileFlags = .Normal;
Platform.BfpFileResult fileResult = .Ok; Platform.BfpFileResult fileResult = .Ok;
mBfpFile = Platform.BfpFile_Create(path.ToScopeCStr!(128), createKind, createFlags, fileFlags, &fileResult); mBfpFile = Platform.Hook.BfpFile_Create(path.ToScopeCStr!(128), createKind, createFlags, fileFlags, &fileResult);
if ((mBfpFile == null) || (fileResult != .Ok)) if ((mBfpFile == null) || (fileResult != .Ok))
{ {
@ -467,7 +467,7 @@ namespace System.IO
newPos = mPos + pos; newPos = mPos + pos;
} }
// Matches the behaviour of Platform.BfpFile_Seek(mBfpFile, value, .Absolute); // Matches the behaviour of Platform.Hook.BfpFile_Seek(mBfpFile, value, .Absolute);
mPos = Math.Max(newPos, 0); mPos = Math.Max(newPos, 0);
if (seekKind == .Absolute && newPos < 0) if (seekKind == .Absolute && newPos < 0)
return .Err; return .Err;
@ -479,7 +479,7 @@ namespace System.IO
{ {
let ret = base.Close(); let ret = base.Close();
if (mBfpFile != null) if (mBfpFile != null)
Platform.BfpFile_Release(mBfpFile); Platform.Hook.BfpFile_Release(mBfpFile);
mBfpFile = null; mBfpFile = null;
mFileAccess = default; mFileAccess = default;
@ -489,12 +489,12 @@ namespace System.IO
protected override void UpdateLength() protected override void UpdateLength()
{ {
mUnderlyingLength = Platform.BfpFile_GetFileSize(mBfpFile); mUnderlyingLength = Platform.Hook.BfpFile_GetFileSize(mBfpFile);
} }
protected Result<void, FileError> SeekUnderlying(int64 offset, Platform.BfpFileSeekKind seekKind = .Absolute) protected Result<void, FileError> SeekUnderlying(int64 offset, Platform.BfpFileSeekKind seekKind = .Absolute)
{ {
int64 newPos = Platform.BfpFile_Seek(mBfpFile, offset, seekKind); int64 newPos = Platform.Hook.BfpFile_Seek(mBfpFile, offset, seekKind);
Result<void, FileError> result = ((seekKind == .Absolute) && (newPos != offset)) ? .Err(.SeekError) : .Ok; Result<void, FileError> result = ((seekKind == .Absolute) && (newPos != offset)) ? .Err(.SeekError) : .Ok;
if (result case .Ok) if (result case .Ok)
mBfpFilePos = newPos; mBfpFilePos = newPos;
@ -507,7 +507,7 @@ namespace System.IO
Try!(SeekUnderlying(pos)); Try!(SeekUnderlying(pos));
Platform.BfpFileResult result = .Ok; Platform.BfpFileResult result = .Ok;
int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, -1, &result); int numBytesRead = Platform.Hook.BfpFile_Read(mBfpFile, data.Ptr, data.Length, -1, &result);
if ((result != .Ok) && (result != .PartialData)) if ((result != .Ok) && (result != .PartialData))
return .Err; return .Err;
mBfpFilePos += numBytesRead; mBfpFilePos += numBytesRead;
@ -520,7 +520,7 @@ namespace System.IO
Try!(SeekUnderlying(pos)); Try!(SeekUnderlying(pos));
Platform.BfpFileResult result = .Ok; Platform.BfpFileResult result = .Ok;
int numBytesRead = Platform.BfpFile_Write(mBfpFile, data.Ptr, data.Length, -1, &result); int numBytesRead = Platform.Hook.BfpFile_Write(mBfpFile, data.Ptr, data.Length, -1, &result);
if ((result != .Ok) && (result != .PartialData)) if ((result != .Ok) && (result != .PartialData))
return .Err; return .Err;
mBfpFilePos += numBytesRead; mBfpFilePos += numBytesRead;
@ -533,7 +533,7 @@ namespace System.IO
Try!(SeekUnderlying(mPos)); Try!(SeekUnderlying(mPos));
Platform.BfpFileResult result = .Ok; Platform.BfpFileResult result = .Ok;
int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, timeoutMS, &result); int numBytesRead = Platform.Hook.BfpFile_Read(mBfpFile, data.Ptr, data.Length, timeoutMS, &result);
if ((result != .Ok) && (result != .PartialData)) if ((result != .Ok) && (result != .PartialData))
{ {
switch (result) switch (result)
@ -560,7 +560,7 @@ namespace System.IO
} }
Platform.BfpFileResult result = .Ok; Platform.BfpFileResult result = .Ok;
Platform.BfpFile_Truncate(mBfpFile, &result); Platform.Hook.BfpFile_Truncate(mBfpFile, &result);
if (result != .Ok) if (result != .Ok)
{ {
Try!(SeekUnderlying(pos)); Try!(SeekUnderlying(pos));
@ -585,7 +585,7 @@ namespace System.IO
{ {
var result = base.Flush(); var result = base.Flush();
if (mBfpFile != null) if (mBfpFile != null)
Platform.BfpFile_Flush(mBfpFile); Platform.Hook.BfpFile_Flush(mBfpFile);
return result; return result;
} }
} }

View file

@ -116,4 +116,98 @@ namespace System.IO
mPosition = 0; mPosition = 0;
} }
} }
class FixedMemoryStream : Stream
{
Span<uint8> mMemory;
int mPosition = 0;
public override int64 Position
{
get
{
return mPosition;
}
set
{
mPosition = (.)value;
}
}
public override int64 Length
{
get
{
return mMemory.Length;
}
}
public override bool CanRead
{
get
{
return true;
}
}
public override bool CanWrite
{
get
{
return true;
}
}
public this(Span<uint8> memory)
{
mMemory = memory;
}
public Span<uint8> Memory => mMemory;
public override Result<int> TryRead(Span<uint8> data)
{
let count = data.Length;
if (count == 0)
return .Ok(0);
int readBytes = Math.Min(count, mMemory.Length - mPosition);
if (readBytes <= 0)
return .Ok(readBytes);
Internal.MemCpy(data.Ptr, &mMemory[mPosition], readBytes);
mPosition += readBytes;
return .Ok(readBytes);
}
public override Result<int> TryWrite(Span<uint8> data)
{
let count = data.Length;
if (count == 0)
return .Ok(0);
int growSize = mPosition + count - mMemory.Length;
if (growSize > 0)
return .Err;
Internal.MemCpy(&mMemory[mPosition], data.Ptr, count);
mPosition += count;
return .Ok(count);
}
public override Result<void> Close()
{
return .Ok;
}
public override Result<void> SetLength(int64 length)
{
return .Err;
}
public void Clear()
{
mMemory.Clear();
mPosition = 0;
}
}
} }

View file

@ -46,7 +46,7 @@ namespace System.IO
Platform.BfpFileAttributes fileFlags = .Normal; Platform.BfpFileAttributes fileFlags = .Normal;
Platform.BfpFileResult fileResult = .Ok; Platform.BfpFileResult fileResult = .Ok;
mBfpFile = Platform.BfpFile_Create(path, createKind, createFlags, fileFlags, &fileResult); mBfpFile = Platform.Hook.BfpFile_Create(path, createKind, createFlags, fileFlags, &fileResult);
if ((mBfpFile == null) || (fileResult != .Ok)) if ((mBfpFile == null) || (fileResult != .Ok))
{ {
@ -83,7 +83,7 @@ namespace System.IO
Platform.BfpFileAttributes fileFlags = .Normal; Platform.BfpFileAttributes fileFlags = .Normal;
Platform.BfpFileResult fileResult = .Ok; Platform.BfpFileResult fileResult = .Ok;
mBfpFile = Platform.BfpFile_Create(path, createKind, createFlags, fileFlags, &fileResult); mBfpFile = Platform.Hook.sBfpFile_Create(path, createKind, createFlags, fileFlags, &fileResult);
if ((mBfpFile == null) || (fileResult != .Ok)) if ((mBfpFile == null) || (fileResult != .Ok))
{ {

View file

@ -66,6 +66,11 @@ namespace System
TempFileError = (int)Result.TempFileError TempFileError = (int)Result.TempFileError
} }
[StaticHook(typeof(SelfOuter))]
public static struct Hook
{
}
#if !BF_RUNTIME_DISABLE #if !BF_RUNTIME_DISABLE
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink]
public static extern uint32 BfpSystem_TickCount(); public static extern uint32 BfpSystem_TickCount();
@ -565,47 +570,47 @@ namespace System
} }
#if !BF_RUNTIME_DISABLE #if !BF_RUNTIME_DISABLE
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern BfpFile* BfpFile_Create(char8* name, BfpFileCreateKind createKind, BfpFileCreateFlags createFlags, BfpFileAttributes createdFileAttrs, BfpFileResult* outResult); public static extern BfpFile* BfpFile_Create(char8* name, BfpFileCreateKind createKind, BfpFileCreateFlags createFlags, BfpFileAttributes createdFileAttrs, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern BfpFile* BfpFile_GetStd(BfpFileStdKind kind, BfpFileResult* outResult); public static extern BfpFile* BfpFile_GetStd(BfpFileStdKind kind, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern int BfpFile_GetSystemHandle(BfpFile* file); public static extern int BfpFile_GetSystemHandle(BfpFile* file);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFile_Release(BfpFile* file); public static extern void BfpFile_Release(BfpFile* file);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern int BfpFile_Write(BfpFile* file, void* buffer, int size, int timeoutMS, BfpFileResult* outResult); public static extern int BfpFile_Write(BfpFile* file, void* buffer, int size, int timeoutMS, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern int BfpFile_Read(BfpFile* file, void* buffer, int size, int timeoutMS, BfpFileResult* outResult); public static extern int BfpFile_Read(BfpFile* file, void* buffer, int size, int timeoutMS, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFile_Flush(BfpFile* file); public static extern void BfpFile_Flush(BfpFile* file);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern int64 BfpFile_GetFileSize(BfpFile* file); public static extern int64 BfpFile_GetFileSize(BfpFile* file);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern int64 BfpFile_Seek(BfpFile* file, int64 offset, BfpFileSeekKind seekKind); public static extern int64 BfpFile_Seek(BfpFile* file, int64 offset, BfpFileSeekKind seekKind);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFile_Truncate(BfpFile* file, BfpFileResult* outResult); public static extern void BfpFile_Truncate(BfpFile* file, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern BfpTimeStamp BfpFile_GetTime_LastWrite(char8* path); public static extern BfpTimeStamp BfpFile_GetTime_LastWrite(char8* path);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern BfpFileAttributes BfpFile_GetAttributes(char8* path, BfpFileResult* outResult); public static extern BfpFileAttributes BfpFile_GetAttributes(char8* path, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFile_SetAttributes(char8* path, BfpFileAttributes attribs, BfpFileResult* outResult); public static extern void BfpFile_SetAttributes(char8* path, BfpFileAttributes attribs, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFile_Copy(char8* oldPath, char8* newPath, BfpFileCopyKind copyKind, BfpFileResult* outResult); public static extern void BfpFile_Copy(char8* oldPath, char8* newPath, BfpFileCopyKind copyKind, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFile_Rename(char8* oldPath, char8* newPath, BfpFileResult* outResult); public static extern void BfpFile_Rename(char8* oldPath, char8* newPath, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFile_Delete(char8* path, BfpFileResult* outResult); public static extern void BfpFile_Delete(char8* path, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern bool BfpFile_Exists(char8* path); public static extern bool BfpFile_Exists(char8* path);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFile_GetTempPath(char8* outPath, int32* inOutPathSize, BfpFileResult* outResult); public static extern void BfpFile_GetTempPath(char8* outPath, int32* inOutPathSize, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFile_GetTempFileName(char8* outName, int32* inOutNameSize, BfpFileResult* outResult); public static extern void BfpFile_GetTempFileName(char8* outName, int32* inOutNameSize, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFile_GetFullPath(char8* inPath, char8* outPath, int32* inOutPathSize, BfpFileResult* outResult); public static extern void BfpFile_GetFullPath(char8* inPath, char8* outPath, int32* inOutPathSize, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFile_GetActualPath(char8* inPath, char8* outPath, int32* inOutPathSize, BfpFileResult* outResult); public static extern void BfpFile_GetActualPath(char8* inPath, char8* outPath, int32* inOutPathSize, BfpFileResult* outResult);
#else #else
@ -660,23 +665,23 @@ namespace System
}; };
#if !BF_RUNTIME_DISABLE #if !BF_RUNTIME_DISABLE
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern BfpFindFileData* BfpFindFileData_FindFirstFile(char8* path, BfpFindFileFlags flags, BfpFileResult* outResult); public static extern BfpFindFileData* BfpFindFileData_FindFirstFile(char8* path, BfpFindFileFlags flags, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern bool BfpFindFileData_FindNextFile(BfpFindFileData* findData); public static extern bool BfpFindFileData_FindNextFile(BfpFindFileData* findData);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFindFileData_GetFileName(BfpFindFileData* findData, char8* outName, int32* inOutNameSize, BfpFileResult* outResult); public static extern void BfpFindFileData_GetFileName(BfpFindFileData* findData, char8* outName, int32* inOutNameSize, BfpFileResult* outResult);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern BfpTimeStamp BfpFindFileData_GetTime_LastWrite(BfpFindFileData* findData); public static extern BfpTimeStamp BfpFindFileData_GetTime_LastWrite(BfpFindFileData* findData);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern BfpTimeStamp BfpFindFileData_GetTime_Created(BfpFindFileData* findData); public static extern BfpTimeStamp BfpFindFileData_GetTime_Created(BfpFindFileData* findData);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern BfpTimeStamp BfpFindFileData_GetTime_Access(BfpFindFileData* findData); public static extern BfpTimeStamp BfpFindFileData_GetTime_Access(BfpFindFileData* findData);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern BfpFileAttributes BfpFindFileData_GetFileAttributes(BfpFindFileData* findData); public static extern BfpFileAttributes BfpFindFileData_GetFileAttributes(BfpFindFileData* findData);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern int64 BfpFindFileData_GetFileSize(BfpFindFileData* findData); public static extern int64 BfpFindFileData_GetFileSize(BfpFindFileData* findData);
[CallingConvention(.Stdcall), CLink] [CallingConvention(.Stdcall), CLink, StaticHook]
public static extern void BfpFindFileData_Release(BfpFindFileData* findData); public static extern void BfpFindFileData_Release(BfpFindFileData* findData);
#else #else
@ -714,6 +719,20 @@ namespace System
Documents Documents
} }
public static bool SetStrHelper(StringView str, char8* outStr, int32* inOutSize, Result* outResult)
{
if (str.Length > *inOutSize + 1)
{
*inOutSize = (.)str.Length + 1;
*outResult = .InsufficientBuffer;
return false;
}
*inOutSize = (.)str.Length + 1;
Internal.MemCpy(outStr, str.Ptr, str.Length);
outStr[str.Length] = 0;
return true;
}
public static Result<void, Platform.Result> GetStrHelper(String outStr, delegate void (char8* outPtr, int32* outSize, Result* outResult) func) public static Result<void, Platform.Result> GetStrHelper(String outStr, delegate void (char8* outPtr, int32* outSize, Result* outResult) func)
{ {
let initSize = 4096; let initSize = 4096;

View file

@ -21,7 +21,7 @@ namespace System
using System.Threading; using System.Threading;
// This class is thread-safe for random results, but not deterministically thread-safe // This class is thread-safe for random results, but not deterministically thread-safe
[StaticInitPriority(100)] [StaticInitPriority(200)]
public class Random public class Random
{ {
// //

View file

@ -14,7 +14,7 @@ namespace System
public bool AVX, AVX2, AVX512; public bool AVX, AVX2, AVX512;
} }
[StaticInitPriority(101)] [StaticInitPriority(201)]
static class Runtime static class Runtime
{ {
const int32 cVersion = 10; const int32 cVersion = 10;
@ -484,6 +484,7 @@ namespace System
public static function ErrorHandlerResult(AssertError.Kind kind, String error, String filePath, int lineNum) CheckAssertError; public static function ErrorHandlerResult(AssertError.Kind kind, String error, String filePath, int lineNum) CheckAssertError;
public static function int32(char8* kind, char8* arg1, char8* arg2, int arg3) CheckErrorHandler; public static function int32(char8* kind, char8* arg1, char8* arg2, int arg3) CheckErrorHandler;
public static function void*(char8* filePath) LibraryLoadCallback;
static ErrorHandlerResult CheckAssertError_Impl(AssertError.Kind kind, String error, String filePath, int lineNum) static ErrorHandlerResult CheckAssertError_Impl(AssertError.Kind kind, String error, String filePath, int lineNum)
{ {

View file

@ -0,0 +1,90 @@
namespace System;
[AttributeUsage(.Types | .Method, .AlwaysIncludeTarget)]
public struct StaticHookAttribute : Attribute, IOnTypeInit
{
Type mSrcType;
Type mDestType;
public this()
{
mSrcType = null;
mDestType = null;
}
public this(Type srcType)
{
mSrcType = srcType;
mDestType = null;
}
public this(Type srcType, Type destType)
{
mSrcType = srcType;
mDestType = destType;
}
[Comptime]
public void OnTypeInit(Type type, Self* prev)
{
var emitStr = scope String();
if (mDestType != null)
{
var hookAttr = mSrcType.GetCustomAttribute<Self>().Value;
for (var methodInfo in mDestType.GetMethods(.Static))
{
if (!methodInfo.HasCustomAttribute<StaticHookAttribute>())
continue;
emitStr.AppendF($"public static function {methodInfo.ReturnType}");
emitStr.Append("(");
methodInfo.GetParamsDecl(emitStr);
emitStr.AppendF($") s{methodInfo.Name};\n");
}
emitStr.Append("\n");
emitStr.Append("static this\n{\n");
for (var methodInfo in mDestType.GetMethods(.Static))
{
if (!methodInfo.HasCustomAttribute<StaticHookAttribute>())
continue;
emitStr.AppendF($"\ts{methodInfo.Name} = {mSrcType}.s{methodInfo.Name} ?? => {hookAttr.mSrcType}.{methodInfo.Name};\n");
emitStr.AppendF($"\t{mSrcType}.s{methodInfo.Name} = => {mDestType}.{methodInfo.Name};\n");
}
emitStr.Append("}\n");
}
else
{
if (mSrcType == null)
return;
emitStr.Append("#pragma warning disable\n");
for (var methodInfo in mSrcType.GetMethods(.Static))
{
if (!methodInfo.HasCustomAttribute<StaticHookAttribute>())
continue;
emitStr.AppendF($"public static function {methodInfo.ReturnType}");
emitStr.Append("(");
methodInfo.GetParamsDecl(emitStr);
emitStr.AppendF($") s{methodInfo.Name};\n");
emitStr.AppendF($"public static {methodInfo.ReturnType} {methodInfo.Name}");
emitStr.Append("(");
methodInfo.GetParamsDecl(emitStr);
emitStr.Append(")\n");
emitStr.Append("{\n");
emitStr.AppendF($"\tif (s{methodInfo.Name} != null)\n");
emitStr.AppendF($"\t\treturn s{methodInfo.Name}(");
methodInfo.GetArgsList(emitStr);
emitStr.AppendF($");\n\treturn {mSrcType}.{methodInfo.Name}(");
methodInfo.GetArgsList(emitStr);
emitStr.Append(");\n}\n\n");
}
}
Compiler.EmitTypeBody(type, emitStr);
}
}

View file

@ -2,7 +2,7 @@ using System.Diagnostics;
using System.Threading; using System.Threading;
namespace System.Text namespace System.Text
{ {
[StaticInitPriority(100)] [StaticInitPriority(200)]
abstract class Encoding abstract class Encoding
{ {
public enum DecodeError public enum DecodeError

View file

@ -8,7 +8,7 @@ namespace System.Threading
public delegate void ThreadStart(); public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(Object obj); public delegate void ParameterizedThreadStart(Object obj);
[StaticInitPriority(100)] [StaticInitPriority(200)]
public sealed class Thread public sealed class Thread
{ {
private int mInternalThread; private int mInternalThread;
@ -28,7 +28,7 @@ namespace System.Threading
public static Thread sMainThread ~ delete _; public static Thread sMainThread ~ delete _;
[StaticInitPriority(102)] [StaticInitPriority(202)]
struct RuntimeThreadInit struct RuntimeThreadInit
{ {
static Object Thread_Alloc() static Object Thread_Alloc()

View file

@ -53,7 +53,7 @@ namespace System {
NoThrowOnInvalidTime = 2 NoThrowOnInvalidTime = 2
} }
[StaticInitPriority(100)] [StaticInitPriority(200)]
sealed public class TimeZoneInfo : IEquatable<TimeZoneInfo> sealed public class TimeZoneInfo : IEquatable<TimeZoneInfo>
{ {
// ---- SECTION: members supporting exposed properties -------------* // ---- SECTION: members supporting exposed properties -------------*