1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-30 05:15:59 +02:00

Moving corlib files out of "System" directory into root

This commit is contained in:
Brian Fiete 2019-09-19 05:46:35 -07:00
parent 4cd58262e4
commit 7dbfd15292
179 changed files with 3 additions and 0 deletions

View file

@ -0,0 +1,301 @@
using System.IO;
using System.Text;
using System.Threading;
using System.Collections.Generic;
namespace System.Diagnostics
{
internal delegate void UserCallBack(String data);
class AsyncStreamReader
{
internal const int32 DefaultBufferSize = 1024; // Byte buffer size
private const int32 MinBufferSize = 128;
private Stream stream;
private Encoding encoding;
private Decoder decoder;
private uint8[] byteBuffer;
private char8[] char8Buffer;
// Record the number of valid bytes in the byteBuffer, for a few checks.
// This is the maximum number of char8s we can get from one call to
// ReadBuffer. Used so ReadBuffer can tell when to copy data into
// a user's char8[] directly, instead of our internal char8[].
private int32 mMaxCharsPerBuffer;
// Store a backpointer to the process class, to check for user callbacks
private Process process;
// Delegate to call user function.
private UserCallBack userCallBack;
// Internal Cancel operation
private bool cancelOperation;
private WaitEvent eofEvent = new WaitEvent() ~ delete _;
private Queue<String> messageQueue ~ delete _;
private String sb;
private bool bLastCarriageReturn;
private Monitor mMonitor = new Monitor();
// Cache the last position scanned in sb when searching for lines.
private int currentLinePos;
internal this(Process process, Stream stream, UserCallBack callback, Encoding encoding)
: this(process, stream, callback, encoding, DefaultBufferSize)
{
}
internal ~this()
{
for (var msg in messageQueue)
delete msg;
Close();
}
// Creates a new AsyncStreamReader for the given stream. The
// character encoding is set by encoding and the buffer size,
// in number of 16-bit characters, is set by bufferSize.
//
internal this(Process process, Stream stream, UserCallBack callback, Encoding encoding, int32 bufferSize)
{
Debug.Assert(process != null && stream != null && encoding != null && callback != null, "Invalid arguments!");
Debug.Assert(stream.CanRead, "Stream must be readable!");
Debug.Assert(bufferSize > 0, "Invalid buffer size!");
Init(process, stream, callback, encoding, bufferSize);
messageQueue = new Queue<String>();
}
public virtual Encoding CurrentEncoding
{
get { return encoding; }
}
public virtual Stream BaseStream
{
get { return stream; }
}
private void Init(Process process, Stream stream, UserCallBack callback, Encoding encoding, int32 bufferSize)
{
this.process = process;
this.stream = stream;
this.encoding = encoding;
this.userCallBack = callback;
int32 useBufferSize = bufferSize;
if (useBufferSize < MinBufferSize) useBufferSize = MinBufferSize;
byteBuffer = new uint8[useBufferSize];
mMaxCharsPerBuffer = (int32)encoding.GetMaxCharCount(useBufferSize);
char8Buffer = new char8[mMaxCharsPerBuffer];
cancelOperation = false;
sb = null;
this.bLastCarriageReturn = false;
}
public virtual void Close()
{
Dispose(true);
}
void Dispose(bool disposing)
{
if (disposing)
{
if (stream != null)
stream.Close();
}
if (stream != null)
{
stream = null;
encoding = null;
decoder = null;
byteBuffer = null;
char8Buffer = null;
}
}
// User calls BeginRead to start the asynchronous read
internal void BeginReadLine()
{
if (cancelOperation)
{
cancelOperation = false;
}
if (sb == null)
{
sb = new String(DefaultBufferSize);
stream.BeginRead(byteBuffer, 0, byteBuffer.Count, new => ReadBuffer, null);
}
else
{
FlushMessageQueue();
}
}
internal void CancelOperation()
{
cancelOperation = true;
}
// This is the async callback function. Only one thread could/should call this.
private void ReadBuffer(IAsyncResult ar)
{
int byteLen = stream.EndRead(ar);
// We should ideally consume errors from operations getting cancelled
// so that we don't crash the unsuspecting parent with an unhandled exc.
// This seems to come in 2 forms of exceptions (depending on platform and scenario),
// namely OperationCanceledException and IOException (for errorcode that we don't
// map explicitly).
byteLen = 0; // Treat this as EOF
if (byteLen == 0)
{
// We're at EOF, we won't call this function again from here on.
using (mMonitor.Enter())
{
if (sb.Length != 0)
{
messageQueue.Enqueue(new String(sb));
sb.Clear();
}
messageQueue.Enqueue(null);
}
// UserCallback could throw, we should still set the eofEvent
FlushMessageQueue();
eofEvent.Set(true);
}
else
{
int char8Len = decoder.GetChars(byteBuffer, 0, byteLen, char8Buffer, 0);
sb.Append(char8Buffer, 0, char8Len);
GetLinesFromStringBuilder();
stream.BeginRead(byteBuffer, 0, byteBuffer.Count, new => ReadBuffer, null);
}
}
// Read lines stored in StringBuilder and the buffer we just read into.
// A line is defined as a sequence of characters followed by
// a carriage return ('\r'), a line feed ('\n'), or a carriage return
// immediately followed by a line feed. The resulting string does not
// contain the terminating carriage return and/or line feed. The returned
// value is null if the end of the input stream has been reached.
//
private void GetLinesFromStringBuilder()
{
int currentIndex = currentLinePos;
int lineStart = 0;
int len = sb.Length;
// skip a beginning '\n' char8acter of new block if last block ended
// with '\r'
if (bLastCarriageReturn && (len > 0) && sb[0] == '\n')
{
currentIndex = 1;
lineStart = 1;
bLastCarriageReturn = false;
}
while (currentIndex < len)
{
char8 ch = sb[currentIndex];
// Note the following common line feed char8s:
// \n - UNIX \r\n - DOS \r - Mac
if (ch == '\r' || ch == '\n')
{
String s = new String();
s.Append(sb, lineStart, currentIndex - lineStart);
lineStart = currentIndex + 1;
// skip the "\n" char8acter following "\r" char8acter
if ((ch == '\r') && (lineStart < len) && (sb[lineStart] == '\n'))
{
lineStart++;
currentIndex++;
}
using (mMonitor.Enter())
{
messageQueue.Enqueue(s);
}
}
currentIndex++;
}
if (sb[len - 1] == '\r')
{
bLastCarriageReturn = true;
}
// Keep the rest char8acaters which can't form a new line in string builder.
if (lineStart < len)
{
if (lineStart == 0)
{
// we found no breaklines, in this case we cache the position
// so next time we don't have to restart from the beginning
currentLinePos = currentIndex;
}
else
{
sb.Remove(0, lineStart);
currentLinePos = 0;
}
}
else
{
sb.Clear();
currentLinePos = 0;
}
FlushMessageQueue();
}
private void FlushMessageQueue()
{
while (true)
{
// When we call BeginReadLine, we also need to flush the queue
// So there could be a ---- between the ReadBuffer and BeginReadLine
// We need to take lock before DeQueue.
if (messageQueue.Count > 0)
{
using (mMonitor.Enter())
{
if (messageQueue.Count > 0)
{
String s = messageQueue.Dequeue();
// skip if the read is the read is cancelled
// this might happen inside UserCallBack
// However, continue to drain the queue
if (!cancelOperation)
{
userCallBack(s);
}
delete s;
}
}
}
else
{
break;
}
}
}
// Wait until we hit EOF. This is called from Process.WaitForExit
// We will lose some information if we don't do this.
internal void WaitUtilEOF()
{
if (eofEvent != null)
{
eofEvent.WaitFor();
}
}
}
}

View file

@ -0,0 +1,37 @@
namespace System.Diagnostics
{
class Check
{
[Unchecked, SkipCall]
public static void Assert(bool condition)
{
}
[Checked]
public static void Assert(bool condition)
{
if (!condition)
Internal.FatalError("Assert failed", 1);
}
[Unchecked, SkipCall]
public static void Assert(bool condition, String error)
{
}
[Checked]
public static void Assert(bool condition, String error)
{
if (!condition)
Internal.FatalError(error, 1);
}
[NoReturn]
[SkipCall]
public static void FatalError(String msg = "Fatal error encountered")
{
Internal.FatalError(msg, 1);
}
}
}

View file

@ -0,0 +1,61 @@
namespace System.Diagnostics.Contracts
{
class Contract
{
public enum ContractFailureKind
{
Precondition,
//[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Postcondition")]
Postcondition,
//[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Postcondition")]
PostconditionOnException,
Invariant,
Assert,
Assume,
}
static extern void ReportFailure(ContractFailureKind failureKind, char8* userMessage, int32 userMessageLen, char8* conditionText, int32 conditionTextLen);
/// <summary>
/// This method is used internally to trigger a failure indicating to the "programmer" that he is using the interface incorrectly.
/// It is NEVER used to indicate failure of actual contracts at runtime.
/// </summary>
static void AssertMustUseRewriter(ContractFailureKind kind, String contractKind)
{
}
public static void Assume(bool condition, StringView userMessage)
{
if (!condition)
{
ReportFailure(ContractFailureKind.Assume, userMessage.Ptr, (int32)userMessage.Length, null, 0);
}
}
public static void Assert(bool condition)
{
if (!condition)
ReportFailure(ContractFailureKind.Assert, null, 0, null, 0);
}
public static void Assert(bool condition, String userMessage)
{
if (!condition)
ReportFailure(ContractFailureKind.Assert, userMessage.Ptr, (int32)userMessage.Length, null, 0);
}
public static void Requires(bool condition)
{
if (!condition)
ReportFailure(ContractFailureKind.Assert, null, 0, null, 0);
//AssertMustUseRewriter(ContractFailureKind.Precondition, "Requires");
}
public static void Requires(bool condition, StringView userMessage)
{
AssertMustUseRewriter(ContractFailureKind.Precondition, "Requires");
}
public static void EndContractBlock() { }
}
}

View file

@ -0,0 +1,6 @@
namespace System.Diagnostics.Contracts
{
class ContractsBcl
{
}
}

View file

@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <copyright file="Process.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Diagnostics
{
using System;
public delegate void DataReceivedEventHandler(Object sender, DataReceivedEventArgs e);
public class DataReceivedEventArgs : EventArgs
{
internal String _data;
internal this(String data)
{
_data = data;
}
public String Data
{
get
{
return _data;
}
}
}
}

View file

@ -0,0 +1,58 @@
namespace System.Diagnostics
{
class Debug
{
#if !DEBUG
[SkipCall]
#endif
public static void Assert(bool condition)
{
if (!condition)
Internal.FatalError("Assert failed", 1);
}
#if !DEBUG
[SkipCall]
#endif
public static void Assert(bool condition, String error)
{
if (!condition)
Internal.FatalError(error, 1);
}
#if !DEBUG
[SkipCall]
#endif
public static void FatalError(String msg = "Fatal error encountered")
{
Internal.FatalError(msg, 1);
}
#if !DEBUG
[SkipCall]
#endif
public static void AssertNotStack(Object obj)
{
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
if ((obj != null) && (obj.GetFlags() & 8 != 0))
Internal.FatalError("Assert failed", 1);
#endif
}
static extern void Write(char8* str, int strLen);
public static void WriteLine(StringView line)
{
Write(line.Ptr, line.Length);
Write("\n", 1);
}
public static void WriteLine(StringView strFormat, params Object[] args)
{
String paramStr = scope String();
paramStr.AppendF(strFormat, params args);
paramStr.Append('\n');
Write(paramStr.Ptr, paramStr.Length);
}
}
}

View file

@ -0,0 +1,593 @@
// This file contains portions of code released by Microsoft under the MIT license as part
// of an open-sourcing initiative in 2014 of the C# core libraries.
// The original source was submitted to https://github.com/Microsoft/referencesource
namespace System.Diagnostics
{
using System.Text;
using System.IO;
using System.Security;
using System;
using System.Globalization;
public class FileVersionInfo
{
public enum Error
{
FileNotFound,
NotSupported
}
private String mFileName ~ delete _;
private String mCompanyName ~ delete _;
private String mFileDescription ~ delete _;
private String mFileVersion ~ delete _;
private String mInternalName ~ delete _;
private String mLegalCopyright ~ delete _;
private String mOriginalFilename ~ delete _;
private String mProductName ~ delete _;
private String mProductVersion ~ delete _;
private String mComments ~ delete _;
private String mLegalTrademarks ~ delete _;
private String mPrivateBuild ~ delete _;
private String mSpecialBuild ~ delete _;
private String mLanguage ~ delete _;
private int32 mFileMajor;
private int32 mFileMinor;
private int32 mFileBuild;
private int32 mFilePrivate;
private int32 mProductMajor;
private int32 mProductMinor;
private int32 mProductBuild;
private int32 mProductPrivate;
private int32 mFileFlags;
public void Dispose()
{
DeleteAndNullify!(mFileName);
DeleteAndNullify!(mCompanyName);
DeleteAndNullify!(mFileDescription);
DeleteAndNullify!(mFileVersion);
DeleteAndNullify!(mInternalName);
DeleteAndNullify!(mLegalCopyright);
DeleteAndNullify!(mOriginalFilename);
DeleteAndNullify!(mProductName);
DeleteAndNullify!(mProductVersion);
DeleteAndNullify!(mComments);
DeleteAndNullify!(mLegalTrademarks);
DeleteAndNullify!(mPrivateBuild);
DeleteAndNullify!(mSpecialBuild);
DeleteAndNullify!(mLanguage);
mFileMajor = 0;
mFileMajor = 0;
mFileBuild = 0;
mFilePrivate = 0;
mProductMajor = 0;
mProductMinor = 0;
mProductBuild = 0;
mProductPrivate = 0;
mFileFlags = 0;
}
/// Gets the comments associated with the file.
public StringView Comments
{
get
{
return mComments;
}
}
/// >Gets the name of the company that produced the file.
public StringView CompanyName
{
get
{
return mCompanyName;
}
}
/// Gets the build number of the file.
public int FileBuildPart
{
get
{
return mFileBuild;
}
}
/// Gets the description of the file.
///
public String FileDescription
{
get
{
return mFileDescription;
}
}
///
/// Gets the major part of the version number.
///
public int FileMajorPart
{
get
{
return mFileMajor;
}
}
///
/// Gets the minor
/// part of the version number of the file.
///
public int FileMinorPart
{
get
{
return mFileMinor;
}
}
///
/// Gets the name of the file that this instance describes.
///
public String FileName
{
get
{
return mFileName;
}
}
///
/// Gets the file private part number.
///
public int FilePrivatePart
{
get
{
return mFilePrivate;
}
}
///
/// Gets the file version number.
///
public String FileVersion
{
get
{
return mFileVersion;
}
}
///
/// Gets the internal name of the file, if one exists.
///
public String InternalName
{
get
{
return mInternalName;
}
}
///
/// Gets a value that specifies whether the file
/// contains debugging information or is compiled with debugging features enabled.
///
public bool IsDebug
{
get
{
#if BF_PLATFORM_WINDOWS
return (mFileFlags & Windows.VS_FF_DEBUG) != 0;
#else
return false;
#endif
}
}
///
/// Gets a value that specifies whether the file has been modified and is not identical to
/// the original shipping file of the same version number.
///
public bool IsPatched
{
get
{
#if BF_PLATFORM_WINDOWS
return (mFileFlags & Windows.VS_FF_PATCHED) != 0;
#else
return false;
#endif
}
}
///
/// Gets a value that specifies whether the file was built using standard release procedures.
///
public bool IsPrivateBuild
{
get
{
#if BF_PLATFORM_WINDOWS
return (mFileFlags & Windows.VS_FF_PRIVATEBUILD) != 0;
#else
return false;
#endif
}
}
///
/// Gets a value that specifies whether the file
/// is a development version, rather than a commercially released product.
///
public bool IsPreRelease
{
get
{
#if BF_PLATFORM_WINDOWS
return (mFileFlags & Windows.VS_FF_PRERELEASE) != 0;
#else
return false;
#endif
}
}
///
/// Gets a value that specifies whether the file is a special build.
///
public bool IsSpecialBuild
{
get
{
#if BF_PLATFORM_WINDOWS
return (mFileFlags & Windows.VS_FF_SPECIALBUILD) != 0;
#else
return false;
#endif
}
}
///
///
/// Gets the default language String for the version info block.
///
///
public String Language
{
get
{
return mLanguage;
}
}
///
/// Gets all copyright notices that apply to the specified file.
///
public String LegalCopyright
{
get
{
return mLegalCopyright;
}
}
///
/// Gets the trademarks and registered trademarks that apply to the file.
///
public String LegalTrademarks
{
get
{
return mLegalTrademarks;
}
}
///
/// Gets the name the file was created with.
///
public String OriginalFilename
{
get
{
return mOriginalFilename;
}
}
///
/// Gets information about a private version of the file.
///
public String PrivateBuild
{
get
{
return mPrivateBuild;
}
}
///
/// Gets the build number of the product this file is associated with.
///
public int ProductBuildPart
{
get
{
return mProductBuild;
}
}
///
/// Gets the major part of the version number for the product this file is associated with.
///
public int ProductMajorPart
{
get
{
return mProductMajor;
}
}
///
/// Gets the minor part of the version number for the product the file is associated with.
///
public int ProductMinorPart
{
get
{
return mProductMinor;
}
}
///
/// Gets the name of the product this file is distributed with.
///
public String ProductName
{
get
{
return mProductName;
}
}
///
/// Gets the private part number of the product this file is associated with.
///
public int ProductPrivatePart
{
get
{
return mProductPrivate;
}
}
///
/// Gets the version of the product this file is distributed with.
///
public String ProductVersion
{
get
{
return mProductVersion;
}
}
///
/// Gets the special build information for the file.
///
public String SpecialBuild
{
get
{
return mSpecialBuild;
}
}
private static void ConvertTo8DigitHex(int value, String s)
{
s.AppendF("{:X8}", value);
}
#if BF_PLATFORM_WINDOWS
private static Windows.VS_FIXEDFILEINFO GetFixedFileInfo(void* memPtr)
{
void* memRef = null;
if (Windows.VerQueryValueW(memPtr, "\\".ToScopedNativeWChar!(), ref memRef, var memLen))
return *(Windows.VS_FIXEDFILEINFO*)memRef;
return .();
}
private static String GetFileVersionLanguage(void* memPtr)
{
int langid = GetVarEntry(memPtr) >> 16;
char16[256] langChars = .(0, ?);
Windows.VerLanguageNameW((uint32)langid, &langChars, (uint32)langChars.Count);
return new String()..Append(&langChars);
}
private static String GetFileVersionString(void* memPtr, String name)
{
String str = new String();
void* memRef = null;
if (Windows.VerQueryValueW(memPtr, name.ToScopedNativeWChar!(), ref memRef, var memLen))
{
if (memRef != null)
{
str.Append((char16*)memRef);
}
}
return str;
}
private static int32 GetVarEntry(void* memPtr)
{
void* memRef = null;
if (Windows.VerQueryValueW(memPtr, "\\VarFileInfo\\Translation".ToScopedNativeWChar!(), ref memRef, var memLen))
{
return ((int32)(*(int16*)(memRef)) << 16) + *(int16*)((uint8*)memRef + 2);
}
return 0x040904E4;
}
//
// This function tries to find version informaiton for a specific codepage.
// Returns true when version information is found.
//
private bool GetVersionInfoForCodePage(void* memIntPtr, String codepage)
{
StringView template = "\\\\StringFileInfo\\\\{0}\\\\{1}";
mCompanyName = GetFileVersionString(memIntPtr, scope String()..AppendF(CultureInfo.InvariantCulture, template, codepage, "CompanyName"));
mFileDescription = GetFileVersionString(memIntPtr, scope String()..AppendF(CultureInfo.InvariantCulture, template, codepage, "FileDescription"));
mFileVersion = GetFileVersionString(memIntPtr, scope String()..AppendF(CultureInfo.InvariantCulture, template, codepage, "FileVersion"));
mInternalName = GetFileVersionString(memIntPtr, scope String()..AppendF(CultureInfo.InvariantCulture, template, codepage, "InternalName"));
mLegalCopyright = GetFileVersionString(memIntPtr, scope String()..AppendF(CultureInfo.InvariantCulture, template, codepage, "LegalCopyright"));
mOriginalFilename = GetFileVersionString(memIntPtr, scope String()..AppendF(CultureInfo.InvariantCulture, template, codepage, "OriginalFilename"));
mProductName = GetFileVersionString(memIntPtr, scope String()..AppendF(CultureInfo.InvariantCulture, template, codepage, "ProductName"));
mProductVersion = GetFileVersionString(memIntPtr, scope String()..AppendF(CultureInfo.InvariantCulture, template, codepage, "ProductVersion"));
mComments = GetFileVersionString(memIntPtr, scope String()..AppendF(CultureInfo.InvariantCulture, template, codepage, "Comments"));
mLegalTrademarks = GetFileVersionString(memIntPtr, scope String()..AppendF(CultureInfo.InvariantCulture, template, codepage, "LegalTrademarks"));
mPrivateBuild = GetFileVersionString(memIntPtr, scope String()..AppendF(CultureInfo.InvariantCulture, template, codepage, "PrivateBuild"));
mSpecialBuild = GetFileVersionString(memIntPtr, scope String()..AppendF(CultureInfo.InvariantCulture, template, codepage, "SpecialBuild"));
mLanguage = GetFileVersionLanguage(memIntPtr);
Windows.VS_FIXEDFILEINFO ffi = GetFixedFileInfo(memIntPtr);
mFileMajor = HIWORD(ffi.dwFileVersionMS);
mFileMinor = LOWORD(ffi.dwFileVersionMS);
mFileBuild = HIWORD(ffi.dwFileVersionLS);
mFilePrivate = LOWORD(ffi.dwFileVersionLS);
mProductMajor = HIWORD(ffi.dwProductVersionMS);
mProductMinor = LOWORD(ffi.dwProductVersionMS);
mProductBuild = HIWORD(ffi.dwProductVersionLS);
mProductPrivate = LOWORD(ffi.dwProductVersionLS);
mFileFlags = (.)ffi.dwFileFlags;
// fileVersion is chosen based on best guess. Other fields can be used if appropriate.
return (mFileVersion != string.Empty);
}
///
/// <para>Returns a System.Windows.Forms.FileVersionInfo representing the version information associated with the specified file.
///
public Result<void, Error> GetVersionInfo(StringView fileName)
{
if (mFileName != null)
{
Dispose();
}
// Check for the existence of the file. File.Exists returns false
// if Read permission is denied.
if (!File.Exists(fileName))
{
//
// The previous version of this code in the success case would require
// one imperative Assert for PathDiscovery permission, one Demand for
// PathDiscovery permission (blocked by the Assert), and 2 demands for
// Read permission. It turns out that File.Exists does a demand for
// Read permission, so in the success case, we only need to do a single Demand.
// In the success case, this change increases the performance of this
// function dramatically.
//
// In the failure case, we want to remain backwardly compatible by throwing
// a SecurityException in the case where Read access is denied
// (it can be argued that this is less secure than throwing a FileNotFoundException,
// but perhaps not so much as to be worth a breaking change).
// File.Exists eats a SecurityException, so we need to Demand for it
// here. Since performance in the failure case is not crucial, as an
// exception will be thrown anyway, we do a Demand for Read access.
// If that does not throw an exception, then we will throw a FileNotFoundException.
//
// We also change the code to do a declarative Assert for PathDiscovery,
// as that performs much better than an imperative Assert.
//
return .Err(.FileNotFound);
}
mFileName = new String(fileName);
char16* wcStr = fileName.ToScopedNativeWChar!();
uint32 handle; // This variable is not used, but we need an out variable.
uint32 infoSize = Windows.GetFileVersionInfoSizeW(wcStr, out handle);
if (infoSize != 0)
{
uint8* memPtr = new:ScopedAlloc! uint8[infoSize]*;
if (Windows.GetFileVersionInfoW(wcStr, 0, infoSize, memPtr))
{
int langid = GetVarEntry(memPtr);
String langStr = scope .();
ConvertTo8DigitHex(langid, langStr);
if (!GetVersionInfoForCodePage(memPtr, langStr))
{
// Some dlls might not contain correct codepage information. In this case we will fail during lookup.
// Explorer will take a few shots in dark by trying following ID:
//
// 040904B0 // US English + CP_UNICODE
// 040904E4 // US English + CP_USASCII
// 04090000 // US English + unknown codepage
// Explorer also randomly guess 041D04B0=Swedish+CP_UNICODE and 040704B0=German+CP_UNICODE) sometimes.
// We will try to simulate similiar behavior here.
int[] ids = scope .(0x040904B0, 0x040904E4, 0x04090000);
for (int id in ids)
{
if (id != langid)
{
String idStr = scope .();
ConvertTo8DigitHex(id, idStr);
if (GetVersionInfoForCodePage(memPtr, idStr))
{
break;
}
}
}
}
}
}
return .Ok;
}
#else
public Result<void, Error> GetVersionInfo(StringView fileName)
{
return .Err(.NotSupported);
}
#endif
private static int32 HIWORD(uint32 val)
{
return (.)((val << 16) & 0xFFFF);
}
private static int32 LOWORD(uint32 val)
{
return (.)(val & 0xFFFF);
}
///
/// <para>Returns a partial list of properties in System.Windows.Forms.FileVersionInfo
/// and their values.
///
public override void ToString(String str)
{
String nl = "\r\n";
str.Append("File: "); str.Append(FileName); str.Append(nl);
str.Append("InternalName: "); str.Append(InternalName); str.Append(nl);
str.Append("OriginalFilename: "); str.Append(OriginalFilename); str.Append(nl);
str.Append("FileVersion: "); str.Append(FileVersion); str.Append(nl);
str.Append("FileDescription: "); str.Append(FileDescription); str.Append(nl);
str.Append("Product: "); str.Append(ProductName); str.Append(nl);
str.Append("ProductVersion: "); str.Append(ProductVersion); str.Append(nl);
str.Append("Debug: "); IsDebug.ToString(str); str.Append(nl);
str.Append("Patched: "); IsPatched.ToString(str); str.Append(nl);
str.Append("PreRelease: "); IsPreRelease.ToString(str); str.Append(nl);
str.Append("PrivateBuild: "); IsPrivateBuild.ToString(str); str.Append(nl);
str.Append("SpecialBuild: "); IsSpecialBuild.ToString(str); str.Append(nl);
str.Append("Language: "); str.Append(Language); str.Append(nl);
}
}
}

View file

@ -0,0 +1,119 @@
using System.IO;
using System.Threading;
using System.Text;
using System.Collections.Generic;
namespace System.Diagnostics
{
class Process
{
Platform.BfpProcess* mProcess;
String mProcessName ~ delete _;
public int32 Id
{
get
{
return Platform.BfpProcess_GetProcessId(mProcess);
}
}
public static int32 CurrentId
{
get
{
return (int32)Platform.BfpProcess_GetCurrentId();
}
}
public bool IsAttached
{
get
{
return mProcess != null;
}
}
public StringView ProcessName
{
get
{
if (mProcessName == null)
{
mProcessName = new String();
Platform.GetStrHelper(mProcessName, scope (outPtr, outSize, outResult) =>
{
Platform.BfpProcess_GetProcessName(mProcess, outPtr, outSize, (Platform.BfpProcessResult*)outResult);
});
}
return mProcessName;
}
}
public ~this()
{
Dispose();
}
public void Dispose()
{
if (mProcess != null)
{
Platform.BfpProcess_Release(mProcess);
mProcess = null;
}
}
public Result<void> GetProcessById(String machineName, int32 processId)
{
if (mProcess != null)
{
Dispose();
}
let bfpProcess = Platform.BfpProcess_GetById((machineName != null) ? machineName : null, processId, null);
if (bfpProcess == null)
return .Err;
mProcess = bfpProcess;
return .Ok;
}
public Result<void> GetProcessById(int32 processId)
{
return GetProcessById(null, processId);
}
public void GetMainWindowTitle(String outTitle)
{
Platform.GetStrHelper(outTitle, scope (outPtr, outSize, outResult) =>
{
Platform.BfpProcess_GetMainWindowTitle(mProcess, outPtr, outSize, (Platform.BfpProcessResult*)outResult);
});
}
public static Result<void> GetProcesses(List<Process> processes)
{
let result = Platform.GetSizedHelper<Platform.BfpProcess*>(scope (outPtr, outSize, outResult) =>
{
Platform.BfpProcess_Enumerate(null, outPtr, outSize, (Platform.BfpProcessResult*)outResult);
});
switch (result)
{
case .Err:
return .Err;
case .Ok(let bfpProcSpan):
for (var proc in bfpProcSpan)
{
let process = new Process();
process.mProcess = proc;
processes.Add(process);
}
delete bfpProcSpan.Ptr;
}
return .Ok;
}
}
}

View file

@ -0,0 +1,18 @@
using System.Collections.Generic;
using System.Threading;
namespace System.Diagnostics
{
internal static class ProcessManager
{
#if BF_PLATFORM_WINDOWS
public static bool IsRemoteMachine(StringView machineName)
{
return Platform.BfpProcess_IsRemoteMachine(machineName.ToScopeCStr!());
}
#endif //BF_PLATFORM_WINDOWS
}
}

View file

@ -0,0 +1,13 @@
namespace System.Diagnostics
{
public enum ProcessPriorityClass
{
Normal = 0x20,
Idle = 0x40,
High = 0x80,
RealTime = 0x100,
BelowNormal = 0x4000,
AboveNormal = 0x8000
}
}

View file

@ -0,0 +1,83 @@
using System.Text;
using System.Collections.Generic;
namespace System.Diagnostics
{
class ProcessStartInfo
{
bool mUseShellExecute = true;
bool mRedirectStandardInput = false;
bool mRedirectStandardOutput = false;
bool mRedirectStandardError = false;
bool mCreateNoWindow = false;
public bool ErrorDialog;
//public Windows.Handle ErrorDialogParentHandle;
//public ProcessWindowStyle WindowStyle;
internal String mFileName = new String() ~ delete _;
internal String mArguments = new String() ~ delete _;
internal String mDirectory = new String() ~ delete _;
internal String mVerb = new String("Open") ~ delete _;
public Dictionary<String, String> mEnvironmentVariables ~ DeleteDictionyAndKeysAndItems!(_);
public bool UseShellExecute { get { return mUseShellExecute; } set { mUseShellExecute = value; } };
public bool RedirectStandardInput { get { return mRedirectStandardInput; } set { mRedirectStandardInput = value; } };
public bool RedirectStandardOutput { get { return mRedirectStandardOutput; } set { mRedirectStandardOutput = value; } };
public bool RedirectStandardError { get { return mRedirectStandardError; } set { mRedirectStandardError = value; } };
public bool CreateNoWindow { get { return mCreateNoWindow; } set { mCreateNoWindow = value; } };
internal Encoding StandardOutputEncoding;
internal Encoding StandardErrorEncoding;
//public bool redirectStandardInput { get { return redirectStandardInput; } set { redirectStandardInput = value; } };
//public bool redirectStandardInput { get { return redirectStandardInput; } set { redirectStandardInput = value; } };
public void GetFileName(String outFileName)
{
if (mFileName != null)
outFileName.Append(mFileName);
}
public void SetFileName(StringView fileName)
{
mFileName.Set(fileName);
}
public void SetWorkingDirectory(StringView fileName)
{
mDirectory.Set(fileName);
}
public void SetArguments(StringView arguments)
{
mArguments.Set(arguments);
}
public void SetVerb(StringView verb)
{
mVerb.Set(verb);
}
public void AddEnvironmentVariable(StringView key, StringView value)
{
if (mEnvironmentVariables == null)
{
mEnvironmentVariables = new Dictionary<String, String>();
Environment.GetEnvironmentVariables(mEnvironmentVariables);
}
Environment.SetEnvironmentVariable(mEnvironmentVariables, key, value);
}
public this()
{
//Debug.WriteLine("ProcStartInfo {0} Verb: {1} Tick: {2}", this, mVerb, (int32)Platform.BfpSystem_TickCount());
}
public this(Process process)
{
}
}
}

View file

@ -0,0 +1,10 @@
namespace System.Diagnostics
{
public enum ProcessWindowStyle
{
Normal,
Hidden,
Minimized,
Maximized
}
}

View file

@ -0,0 +1,95 @@
using System.Threading;
namespace System.Diagnostics
{
enum ProfilerScope
{
Thread,
Process
}
struct ProfileInstance : int32
{
public void Dispose()
{
String str = scope String();
str.Append("StopSampling\t");
((int32)this).ToString(str);
Internal.ProfilerCmd(str);
}
}
class Profiler
{
public enum Priority
{
Low,
Normal,
High
}
static int32 gProfileId = 1;
public struct AutoLeave
{
//Profiler mProfiler;
public this(/*Profiler profiler*/)
{
//mProfiler = profiler;
}
void Dispose()
{
Profiler.LeaveSection();
}
}
static Result<ProfileInstance> StartSampling(int threadId, StringView profileDesc, int sampleRate)
{
int32 curId = Interlocked.Increment(ref gProfileId);
String str = scope String();
str.Append("StartSampling\t");
curId.ToString(str);
str.Append("\t");
threadId.ToString(str);
str.Append("\t");
sampleRate.ToString(str);
str.Append("\t");
str.Append(profileDesc);
Internal.ProfilerCmd(str);
return (ProfileInstance)curId;
}
public static Result<ProfileInstance> StartSampling(Thread thread, StringView profileDesc = default, int sampleRate = -1)
{
return StartSampling(thread.Id, profileDesc, sampleRate);
}
public static Result<ProfileInstance> StartSampling(StringView profileDesc = default, int sampleRate = -1)
{
return StartSampling(0, profileDesc, sampleRate);
}
public static void ClearSampling()
{
Internal.ProfilerCmd("ClearSampling");
}
public void Mark()
{
}
public static AutoLeave EnterSection(StringView name, Priority priority = Priority.Normal)
{
return AutoLeave();
}
public static void LeaveSection()
{
}
}
}

View file

@ -0,0 +1,151 @@
using System.IO;
using System.Collections.Generic;
namespace System.Diagnostics
{
class SpawnedProcess
{
public enum KillFlags
{
None = 0,
KillChildren = 1
}
Platform.BfpSpawn* mSpawn;
int mExitCode = 0;
bool mIsDone;
public int ExitCode
{
get
{
if (!mIsDone)
WaitFor(-1);
return mExitCode;
}
}
public bool HasExited
{
get
{
if (!mIsDone)
WaitFor(0);
return mIsDone;
}
}
public this()
{
mSpawn = null;
}
public ~this()
{
Close();
}
public Result<void> Start(ProcessStartInfo startInfo)
{
String fileName = startInfo.mFileName;
Platform.BfpSpawnFlags spawnFlags = .None;
if (startInfo.ErrorDialog)
spawnFlags |= .ErrorDialog;
if (startInfo.UseShellExecute)
{
spawnFlags |= .UseShellExecute;
if (!startInfo.mVerb.IsEmpty)
fileName = scope:: String(fileName, "|", startInfo.mVerb);
}
if (startInfo.CreateNoWindow)
spawnFlags |= .NoWindow;
if (startInfo.RedirectStandardInput)
spawnFlags |= .RedirectStdInput;
if (startInfo.RedirectStandardOutput)
spawnFlags |= .RedirectStdOutput;
if (startInfo.RedirectStandardError)
spawnFlags |= .RedirectStdError;
//startInfo.mEnvironmentVariables
List<char8> env = scope List<char8>();
if (startInfo.mEnvironmentVariables != null)
Environment.EncodeEnvironmentVariables(startInfo.mEnvironmentVariables, env);
Span<char8> envSpan = env;
Platform.BfpSpawnResult result = .Ok;
mSpawn = Platform.BfpSpawn_Create(fileName, startInfo.mArguments, startInfo.mDirectory, envSpan.Ptr, spawnFlags, &result);
if ((mSpawn == null) || (result != .Ok))
return .Err;
return .Ok;
}
public Result<void> AttachStandardInput(FileStream stream)
{
if (mSpawn == null)
return .Err;
Platform.BfpFile* bfpFile = null;
Platform.BfpSpawn_GetStdHandles(mSpawn, &bfpFile, null, null);
if (bfpFile == null)
return .Err;
stream.Attach(bfpFile);
return .Ok;
}
public Result<void> AttachStandardOutput(FileStream stream)
{
if (mSpawn == null)
return .Err;
Platform.BfpFile* bfpFile = null;
Platform.BfpSpawn_GetStdHandles(mSpawn, null, &bfpFile, null);
if (bfpFile == null)
return .Err;
stream.Attach(bfpFile);
return .Ok;
}
public Result<void> AttachStandardError(FileStream stream)
{
if (mSpawn == null)
return .Err;
Platform.BfpFile* bfpFile = null;
Platform.BfpSpawn_GetStdHandles(mSpawn, null, null, &bfpFile);
if (bfpFile == null)
return .Err;
stream.Attach(bfpFile);
return .Ok;
}
public bool WaitFor(int waitMS = -1)
{
if (mSpawn == null)
return true;
if (!Platform.BfpSpawn_WaitFor(mSpawn, waitMS, &mExitCode, null))
{
return false;
}
mIsDone = true;
return true;
}
public void Close()
{
if (mSpawn != null)
{
Platform.BfpSpawn_Release(mSpawn);
mSpawn = null;
}
}
public void Kill(int32 exitCode = 0, KillFlags killFlags = .None)
{
if (mSpawn != null)
{
Platform.BfpSpawn_Kill(mSpawn, exitCode, (Platform.BfpKillFlags)killFlags, null);
}
}
}
}

View file

@ -0,0 +1,142 @@
// This file contains portions of code released by Microsoft under the MIT license as part
// of an open-sourcing initiative in 2014 of the C# core libraries.
// The original source was submitted to https://github.com/Microsoft/referencesource
using System;
namespace System.Diagnostics
{
public class Stopwatch
{
private const int64 TicksPerMillisecond = 1000;
private const int64 TicksPerSecond = TicksPerMillisecond * 1000;
private int64 elapsed;
private int64 startTimeStamp;
private bool isRunning;
public void Start()
{
// Calling start on a running Stopwatch is a no-op.
if (!isRunning)
{
startTimeStamp = GetTimestamp();
isRunning = true;
}
}
public void CopyFrom(Stopwatch sw)
{
elapsed = sw.elapsed;
startTimeStamp = sw.startTimeStamp;
isRunning = sw.isRunning;
}
public this()
{
}
public this(bool startNow)
{
if (startNow)
Start();
}
public ~this()
{
}
public static Stopwatch StartNew()
{
Stopwatch s = new Stopwatch();
s.Start();
return s;
}
public void Stop()
{
// Calling stop on a stopped Stopwatch is a no-op.
if (isRunning)
{
int64 endTimeStamp = GetTimestamp();
int64 elapsedThisPeriod = endTimeStamp - startTimeStamp;
elapsed += elapsedThisPeriod;
isRunning = false;
if (elapsed < 0)
{
// When measuring small time periods the StopWatch.Elapsed*
// properties can return negative values. This is due to
// bugs in the basic input/output system (BIOS) or the hardware
// abstraction layer (HAL) on machines with variable-speed CPUs
// (e.g. Intel SpeedStep).
elapsed = 0;
}
}
}
public void Reset()
{
elapsed = 0;
isRunning = false;
startTimeStamp = 0;
}
// Convenience method for replacing {sw.Reset(); sw.Start();} with a single sw.Restart()
public void Restart()
{
elapsed = 0;
startTimeStamp = GetTimestamp();
isRunning = true;
}
public bool IsRunning
{
get { return isRunning; }
}
public TimeSpan Elapsed
{
get { return TimeSpan(GetElapsedDateTimeTicks()); }
}
public int64 ElapsedMilliseconds
{
get { return GetRawElapsedTicks() / TicksPerMillisecond; }
}
public int64 ElapsedMicroseconds
{
get { return GetRawElapsedTicks(); }
}
public static int64 GetTimestamp()
{
return Internal.GetTickCountMicro();
}
// Get the elapsed ticks.
private int64 GetRawElapsedTicks()
{
int64 timeElapsed = elapsed;
if (isRunning)
{
// If the StopWatch is running, add elapsed time since
// the Stopwatch is started last time.
int64 currentTimeStamp = GetTimestamp();
int64 elapsedUntilNow = currentTimeStamp - startTimeStamp;
timeElapsed += elapsedUntilNow;
}
return timeElapsed;
}
// Get the elapsed ticks.
private int64 GetElapsedDateTimeTicks()
{
return GetRawElapsedTicks() * 10;
}
}
}