mirror of
https://github.com/beefytech/Beef.git
synced 2025-07-07 08:45:59 +02:00
Merge branch 'master' into bufstream-fixes
This commit is contained in:
commit
92738418eb
243 changed files with 19052 additions and 2933 deletions
|
@ -35,7 +35,8 @@ namespace System
|
|||
}
|
||||
|
||||
public bool IsEmpty
|
||||
{
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mLength == 0;
|
||||
|
@ -259,6 +260,46 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
public ref T this[Index index]
|
||||
{
|
||||
[Checked, Inline]
|
||||
get
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mLength - offset;
|
||||
}
|
||||
if ((uint)idx >= (uint)mLength)
|
||||
Internal.ThrowIndexOutOfRange(1);
|
||||
return ref (&mFirstElement)[idx];
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
get
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mLength - offset;
|
||||
}
|
||||
return ref (&mFirstElement)[idx];
|
||||
}
|
||||
}
|
||||
|
||||
public Span<T> this[IndexRange range]
|
||||
{
|
||||
#if !DEBUG
|
||||
[Inline]
|
||||
#endif
|
||||
get
|
||||
{
|
||||
return Span<T>(&mFirstElement, mLength)[range];
|
||||
}
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public T* CArray()
|
||||
{
|
||||
|
@ -276,7 +317,7 @@ namespace System
|
|||
Debug.Assert(length >= 0);
|
||||
Debug.Assert((uint)srcOffset + (uint)length <= (uint)mLength);
|
||||
Debug.Assert((uint)dstOffset + (uint)length <= (uint)arrayTo.mLength);
|
||||
Internal.MemCpy(&arrayTo.GetRef(dstOffset), &GetRef(srcOffset), strideof(T) * length, alignof(T));
|
||||
Internal.MemMove(&arrayTo.GetRef(dstOffset), &GetRef(srcOffset), strideof(T) * length, alignof(T));
|
||||
}
|
||||
|
||||
public void CopyTo<T2>(T2[] arrayTo, int srcOffset, int dstOffset, int length) where T2 : operator explicit T
|
||||
|
@ -299,17 +340,18 @@ namespace System
|
|||
public void CopyTo(Span<T> destination)
|
||||
{
|
||||
Debug.Assert(destination.[Friend]mLength >= mLength);
|
||||
Internal.MemCpy(destination.Ptr, &GetRef(0), strideof(T) * mLength, alignof(T));
|
||||
Internal.MemMove(destination.Ptr, &GetRef(0), strideof(T) * mLength, alignof(T));
|
||||
}
|
||||
|
||||
public void CopyTo(Span<T> destination, int srcOffset)
|
||||
{
|
||||
Debug.Assert((uint)srcOffset + (uint)destination.[Friend]mLength <= (uint)mLength);
|
||||
Internal.MemCpy(destination.Ptr, &GetRef(srcOffset), strideof(T) * (destination.[Friend]mLength - srcOffset), alignof(T));
|
||||
Internal.MemMove(destination.Ptr, &GetRef(srcOffset), strideof(T) * (destination.[Friend]mLength - srcOffset), alignof(T));
|
||||
}
|
||||
|
||||
public void CopyTo<T2>(Span<T2> destination, int srcOffset) where T2 : operator explicit T
|
||||
{
|
||||
//TODO: Handle src/dest overlap (MemMove)
|
||||
Debug.Assert((uint)srcOffset + (uint)destination.[Friend]mLength <= (uint)mLength);
|
||||
var ptr = destination.[Friend]mPtr;
|
||||
for (int i = 0; i < destination.[Friend]mLength; i++)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace System
|
||||
{
|
||||
struct Char16 : char16, IHashable, IIsNaN
|
||||
struct Char16 : char16, ICharacter, IHashable, IIsNaN
|
||||
{
|
||||
const int UNICODE_PLANE00_END = 0x00ffff;
|
||||
// The starting codepoint for Unicode plane 1. Plane 1 contains 0x010000 ~ 0x01ffff.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace System
|
||||
{
|
||||
struct Char32 : char32, IHashable, IIsNaN
|
||||
struct Char32 : char32, ICharacter, IHashable, IIsNaN
|
||||
{
|
||||
public int GetHashCode()
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace System
|
||||
{
|
||||
#unwarn
|
||||
struct Char8 : char8, IHashable, IIsNaN
|
||||
struct Char8 : char8, ICharacter, IHashable, IIsNaN
|
||||
{
|
||||
bool IIsNaN.IsNaN
|
||||
{
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace System.Collections
|
|||
{
|
||||
public TKey mKey; // Key of entry
|
||||
public TValue mValue; // Value of entry
|
||||
public int32 mHashCode; // Lower 31 bits of hash code, -1 if unused
|
||||
public int_cosize mHashCode; // some bits of hash code, -1 if unused
|
||||
public int_cosize mNext; // Index of next entry, -1 if last
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ namespace System.Collections
|
|||
Entry* mEntries;
|
||||
int_cosize mAllocSize;
|
||||
int_cosize mCount;
|
||||
int_cosize mFreeList;
|
||||
int_cosize mFreeList;
|
||||
int_cosize mFreeCount;
|
||||
#if VERSION_DICTIONARY
|
||||
private int32 mVersion;
|
||||
|
@ -258,21 +258,9 @@ namespace System.Collections
|
|||
|
||||
public bool ContainsValue(TValue value)
|
||||
{
|
||||
if (value == null)
|
||||
for (int_cosize i = 0; i < mCount; i++)
|
||||
{
|
||||
for (int_cosize i = 0; i < mCount; i++)
|
||||
{
|
||||
if (mEntries[i].mHashCode >= 0 && mEntries[i].mValue == null) return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: IMPORTANT!
|
||||
/*EqualityComparer<TValue> c = EqualityComparer<TValue>.Default;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (entries[i].hashCode >= 0 && c.Equals(entries[i].value, value)) return true;
|
||||
}*/
|
||||
if (mEntries[i].mHashCode >= 0 && mEntries[i].mValue == value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -289,6 +277,19 @@ namespace System.Collections
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ContainsAlt<TAltKey>((TAltKey key, TValue value) kvPair) where TAltKey : IHashable where bool : operator TKey == TAltKey
|
||||
{
|
||||
TValue value;
|
||||
if (TryGetValueAlt(kvPair.key, out value))
|
||||
{
|
||||
return value == kvPair.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(Span<KeyValuePair> kvPair)
|
||||
{
|
||||
|
@ -306,12 +307,21 @@ namespace System.Collections
|
|||
return Enumerator(this, Enumerator.[Friend]KeyValuePair);
|
||||
}
|
||||
|
||||
static int_cosize GetKeyHash(int hashCode)
|
||||
{
|
||||
if (sizeof(int) == 4)
|
||||
return (int32)hashCode & 0x7FFFFFFF;
|
||||
if (sizeof(int_cosize) == 8)
|
||||
return (int_cosize)(hashCode & 0x7FFFFFFF'FFFFFFFFL);
|
||||
return ((int32)hashCode ^ (int32)((int64)hashCode >> 33)) & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
[DisableObjectAccessChecks]
|
||||
private int FindEntry(TKey key)
|
||||
{
|
||||
if (mBuckets != null)
|
||||
{
|
||||
int hashCode = key.GetHashCode() & 0x7FFFFFFF;
|
||||
int_cosize hashCode = GetKeyHash(key.GetHashCode());
|
||||
for (int i = mBuckets[hashCode % mAllocSize]; i >= 0; i = mEntries[i].mNext)
|
||||
{
|
||||
if (mEntries[i].mHashCode == hashCode && (mEntries[i].mKey == key)) return i;
|
||||
|
@ -329,7 +339,7 @@ namespace System.Collections
|
|||
{
|
||||
if (mBuckets != null)
|
||||
{
|
||||
int_cosize hashCode = (int_cosize)key.GetHashCode() & 0x7FFFFFFF;
|
||||
int_cosize hashCode = GetKeyHash(key.GetHashCode());
|
||||
for (int_cosize i = mBuckets[hashCode % mAllocSize]; i >= 0; i = mEntries[i].mNext)
|
||||
{
|
||||
if (mEntries[i].mHashCode == hashCode && (mEntries[i].mKey == key)) return i;
|
||||
|
@ -350,10 +360,10 @@ namespace System.Collections
|
|||
private void Insert(TKey key, TValue value, bool add)
|
||||
{
|
||||
if (mBuckets == null) Initialize(0);
|
||||
int32 hashCode = (int32)key.GetHashCode() & 0x7FFFFFFF;
|
||||
int_cosize targetBucket = hashCode % (int_cosize)mAllocSize;
|
||||
int_cosize hashCode = GetKeyHash(key.GetHashCode());
|
||||
int targetBucket = hashCode % mAllocSize;
|
||||
|
||||
for (int_cosize i = mBuckets[targetBucket]; i >= 0; i = mEntries[i].mNext)
|
||||
for (int i = mBuckets[targetBucket]; i >= 0; i = mEntries[i].mNext)
|
||||
{
|
||||
if (mEntries[i].mHashCode == hashCode && (mEntries[i].mKey == key))
|
||||
{
|
||||
|
@ -402,7 +412,7 @@ namespace System.Collections
|
|||
private bool Insert(TKey key, bool add, out TKey* keyPtr, out TValue* valuePtr, Entry** outOldData)
|
||||
{
|
||||
if (mBuckets == null) Initialize(0);
|
||||
int32 hashCode = (int32)key.GetHashCode() & 0x7FFFFFFF;
|
||||
int_cosize hashCode = GetKeyHash(key.GetHashCode());
|
||||
int_cosize targetBucket = hashCode % (int_cosize)mAllocSize;
|
||||
for (int_cosize i = mBuckets[targetBucket]; i >= 0; i = mEntries[i].mNext)
|
||||
{
|
||||
|
@ -458,9 +468,9 @@ namespace System.Collections
|
|||
private bool InsertAlt<TAltKey>(TAltKey key, bool add, out TKey* keyPtr, out TValue* valuePtr, Entry** outOldData) where TAltKey : IHashable where bool : operator TKey == TAltKey
|
||||
{
|
||||
if (mBuckets == null) Initialize(0);
|
||||
int32 hashCode = (int32)key.GetHashCode() & 0x7FFFFFFF;
|
||||
int_cosize targetBucket = hashCode % (int_cosize)mAllocSize;
|
||||
for (int_cosize i = mBuckets[targetBucket]; i >= 0; i = mEntries[i].mNext)
|
||||
int_cosize hashCode = GetKeyHash(key.GetHashCode());
|
||||
int targetBucket = hashCode % (int_cosize)mAllocSize;
|
||||
for (int i = mBuckets[targetBucket]; i >= 0; i = mEntries[i].mNext)
|
||||
{
|
||||
if (mEntries[i].mHashCode == hashCode && (mEntries[i].mKey == key))
|
||||
{
|
||||
|
@ -541,7 +551,7 @@ namespace System.Collections
|
|||
{
|
||||
if (newEntries[i].mHashCode != -1)
|
||||
{
|
||||
newEntries[i].mHashCode = (int32)newEntries[i].mKey.GetHashCode() & 0x7FFFFFFF;
|
||||
newEntries[i].mHashCode = GetKeyHash(newEntries[i].mKey.GetHashCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -572,7 +582,7 @@ namespace System.Collections
|
|||
{
|
||||
if (mBuckets != null)
|
||||
{
|
||||
int hashCode = key.GetHashCode() & 0x7FFFFFFF;
|
||||
int_cosize hashCode = GetKeyHash(key.GetHashCode());
|
||||
int bucket = hashCode % (int_cosize)mAllocSize;
|
||||
int last = -1;
|
||||
for (int_cosize i = mBuckets[bucket]; i >= 0; last = i,i = mEntries[i].mNext)
|
||||
|
@ -609,7 +619,7 @@ namespace System.Collections
|
|||
{
|
||||
if (mBuckets != null)
|
||||
{
|
||||
int hashCode = key.GetHashCode() & 0x7FFFFFFF;
|
||||
int_cosize hashCode = GetKeyHash(key.GetHashCode());
|
||||
int bucket = hashCode % (int_cosize)mAllocSize;
|
||||
int last = -1;
|
||||
for (int_cosize i = mBuckets[bucket]; i >= 0; last = i,i = mEntries[i].mNext)
|
||||
|
@ -653,8 +663,8 @@ namespace System.Collections
|
|||
if (mBuckets != null)
|
||||
{
|
||||
|
||||
int_cosize hashCode = (int_cosize)key.GetHashCode() & 0x7FFFFFFF;
|
||||
int_cosize bucket = hashCode % (int_cosize)mAllocSize;
|
||||
int_cosize hashCode = GetKeyHash(key.GetHashCode());
|
||||
int bucket = hashCode % (int_cosize)mAllocSize;
|
||||
int_cosize last = -1;
|
||||
for (int_cosize i = mBuckets[bucket]; i >= 0; last = i,i = mEntries[i].mNext)
|
||||
{
|
||||
|
@ -694,8 +704,8 @@ namespace System.Collections
|
|||
if (mBuckets != null)
|
||||
{
|
||||
|
||||
int_cosize hashCode = (int_cosize)key.GetHashCode() & 0x7FFFFFFF;
|
||||
int_cosize bucket = hashCode % (int_cosize)mAllocSize;
|
||||
int_cosize hashCode = GetKeyHash(key.GetHashCode());
|
||||
int bucket = hashCode % (int_cosize)mAllocSize;
|
||||
int_cosize last = -1;
|
||||
for (int_cosize i = mBuckets[bucket]; i >= 0; last = i,i = mEntries[i].mNext)
|
||||
{
|
||||
|
@ -742,6 +752,18 @@ namespace System.Collections
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool TryGetValueAlt<TAltKey>(TAltKey key, out TValue value) where TAltKey : IHashable where bool : operator TKey == TAltKey
|
||||
{
|
||||
int_cosize i = (int_cosize)FindEntryAlt<TAltKey>(key);
|
||||
if (i >= 0)
|
||||
{
|
||||
value = mEntries[i].mValue;
|
||||
return true;
|
||||
}
|
||||
value = default(TValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryGet(TKey key, out TKey matchKey, out TValue value)
|
||||
{
|
||||
int_cosize i = (int_cosize)FindEntry(key);
|
||||
|
@ -876,6 +898,16 @@ namespace System.Collections
|
|||
mDictionary.mEntries[mCurrentIndex].mValue = value;
|
||||
}
|
||||
|
||||
public void Remove() mut
|
||||
{
|
||||
int_cosize curIdx = mIndex - 1;
|
||||
mDictionary.Remove(mDictionary.mEntries[curIdx].mKey);
|
||||
#if VERSION_DICTIONARY
|
||||
mVersion = mDictionary.mVersion;
|
||||
#endif
|
||||
mIndex = curIdx;
|
||||
}
|
||||
|
||||
public void Reset() mut
|
||||
{
|
||||
#if VERSION_DICTIONARY
|
||||
|
@ -1017,6 +1049,16 @@ namespace System.Collections
|
|||
{
|
||||
}
|
||||
|
||||
public void Remove() mut
|
||||
{
|
||||
int_cosize curIdx = mIndex - 1;
|
||||
mDictionary.Remove(mDictionary.mEntries[curIdx].mKey);
|
||||
#if VERSION_DICTIONARY
|
||||
mVersion = mDictionary.mVersion;
|
||||
#endif
|
||||
mIndex = curIdx;
|
||||
}
|
||||
|
||||
public void Reset() mut
|
||||
{
|
||||
#if VERSION_DICTIONARY
|
||||
|
@ -1113,6 +1155,16 @@ namespace System.Collections
|
|||
{
|
||||
}
|
||||
|
||||
public void Remove() mut
|
||||
{
|
||||
int_cosize curIdx = mIndex - 1;
|
||||
mDictionary.Remove(mDictionary.mEntries[curIdx].mKey);
|
||||
#if VERSION_DICTIONARY
|
||||
mVersion = mDictionary.mVersion;
|
||||
#endif
|
||||
mIndex = curIdx;
|
||||
}
|
||||
|
||||
public void Reset() mut
|
||||
{
|
||||
#if VERSION_DICTIONARY
|
||||
|
|
|
@ -196,7 +196,13 @@ namespace System.Collections
|
|||
return false;
|
||||
}
|
||||
|
||||
[Obsolete("Method renamed to ContainsAlt", false)]
|
||||
public bool ContainsWith<TAltKey>(TAltKey item) where TAltKey : IHashable where bool : operator T == TAltKey
|
||||
{
|
||||
return ContainsAlt(item);
|
||||
}
|
||||
|
||||
public bool ContainsAlt<TAltKey>(TAltKey item) where TAltKey : IHashable where bool : operator T == TAltKey
|
||||
{
|
||||
if (mBuckets != null)
|
||||
{
|
||||
|
@ -346,6 +352,11 @@ namespace System.Collections
|
|||
return Add(item, out entryPtr);
|
||||
}
|
||||
|
||||
public bool TryAddAlt<TAltKey>(TAltKey item, out T* entryPtr) where TAltKey : IHashable where bool : operator T == TAltKey
|
||||
{
|
||||
return AddAlt(item, out entryPtr);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array) { CopyTo(array, 0, mCount); }
|
||||
|
||||
public void CopyTo(T[] array, int32 arrayIndex, int32 count)
|
||||
|
@ -632,6 +643,71 @@ namespace System.Collections
|
|||
mVersion++;
|
||||
#endif
|
||||
|
||||
#if FEATURE_RANDOMIZED_STRING_HASHING && !FEATURE_NETCORE
|
||||
if(collisionCount > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(m_comparer)) {
|
||||
m_comparer = (IEqualityComparer<T>) HashHelpers.GetRandomizedEqualityComparer(m_comparer);
|
||||
SetCapacity(m_buckets.Length, true);
|
||||
}
|
||||
#endif // FEATURE_RANDOMIZED_STRING_HASHING
|
||||
|
||||
entryPtr = &mSlots[index].mValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Adds value to HashSet if not contained already
|
||||
/// @return true if added and false if already present
|
||||
/// @param value value to find
|
||||
/// @param entryPtr ponter to entry
|
||||
public bool AddAlt<TAltKey>(TAltKey value, out T* entryPtr) where TAltKey : IHashable where bool : operator T == TAltKey
|
||||
{
|
||||
if (mBuckets == null)
|
||||
{
|
||||
Initialize(0);
|
||||
}
|
||||
|
||||
int32 hashCode = (int32)InternalGetHashCodeAlt(value);
|
||||
int32 bucket = hashCode % (int32)mBuckets.Count;
|
||||
#if FEATURE_RANDOMIZED_STRING_HASHING && !FEATURE_NETCORE
|
||||
int collisionCount = 0;
|
||||
#endif
|
||||
for (int32 i = mBuckets[hashCode % mBuckets.Count] - 1; i >= 0; i = mSlots[i].mNext)
|
||||
{
|
||||
if (mSlots[i].mHashCode == hashCode && /*m_comparer.Equals*/(mSlots[i].mValue == value))
|
||||
{
|
||||
entryPtr = &mSlots[i].mValue;
|
||||
return false;
|
||||
}
|
||||
#if FEATURE_RANDOMIZED_STRING_HASHING && !FEATURE_NETCORE
|
||||
collisionCount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32 index;
|
||||
if (mFreeList >= 0)
|
||||
{
|
||||
index = mFreeList;
|
||||
mFreeList = mSlots[index].mNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mLastIndex == mSlots.Count)
|
||||
{
|
||||
IncreaseCapacity();
|
||||
// this will change during resize
|
||||
bucket = hashCode % (int32)mBuckets.Count;
|
||||
}
|
||||
index = mLastIndex;
|
||||
mLastIndex++;
|
||||
}
|
||||
mSlots[index].mHashCode = hashCode;
|
||||
//mSlots[index].mValue = value;
|
||||
mSlots[index].mNext = mBuckets[bucket] - 1;
|
||||
mBuckets[bucket] = index + 1;
|
||||
mCount++;
|
||||
#if VERSION_HASHSET
|
||||
mVersion++;
|
||||
#endif
|
||||
|
||||
#if FEATURE_RANDOMIZED_STRING_HASHING && !FEATURE_NETCORE
|
||||
if(collisionCount > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(m_comparer)) {
|
||||
m_comparer = (IEqualityComparer<T>) HashHelpers.GetRandomizedEqualityComparer(m_comparer);
|
||||
|
@ -1071,6 +1147,15 @@ namespace System.Collections
|
|||
return item.GetHashCode() & Lower31BitMask;
|
||||
}
|
||||
|
||||
private int InternalGetHashCodeAlt<TAltKey>(TAltKey item) where TAltKey : IHashable
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return item.GetHashCode() & Lower31BitMask;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// used for set checking operations (using enumerables) that rely on counting
|
||||
|
|
|
@ -148,6 +148,7 @@ namespace System.Collections
|
|||
|
||||
public int Count
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mSize;
|
||||
|
@ -210,6 +211,76 @@ namespace System.Collections
|
|||
}
|
||||
}
|
||||
|
||||
public ref T this[Index index]
|
||||
{
|
||||
[Checked]
|
||||
get
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mSize - offset;
|
||||
}
|
||||
Runtime.Assert((uint)idx < (uint)mSize);
|
||||
return ref mItems[idx];
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
get
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mSize - offset;
|
||||
}
|
||||
return ref mItems[idx];
|
||||
}
|
||||
|
||||
[Checked]
|
||||
set
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mSize - offset;
|
||||
}
|
||||
Runtime.Assert((uint)idx < (uint)mSize);
|
||||
mItems[idx] = value;
|
||||
#if VERSION_LIST
|
||||
mVersion++;
|
||||
#endif
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
set
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mSize - offset;
|
||||
}
|
||||
mItems[idx] = value;
|
||||
#if VERSION_LIST
|
||||
mVersion++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public Span<T> this[IndexRange range]
|
||||
{
|
||||
#if !DEBUG
|
||||
[Inline]
|
||||
#endif
|
||||
get
|
||||
{
|
||||
return Span<T>(mItems, mSize)[range];
|
||||
}
|
||||
}
|
||||
|
||||
public ref T Front
|
||||
{
|
||||
get
|
||||
|
@ -534,7 +605,7 @@ namespace System.Collections
|
|||
if (mSize == AllocSize) EnsureCapacity(mSize + 1, true);
|
||||
if (index < mSize)
|
||||
{
|
||||
Internal.MemCpy(mItems + index + 1, mItems + index, (mSize - index) * strideof(T), alignof(T));
|
||||
Internal.MemMove(mItems + index + 1, mItems + index, (mSize - index) * strideof(T), alignof(T));
|
||||
}
|
||||
mItems[index] = item;
|
||||
mSize++;
|
||||
|
@ -553,7 +624,7 @@ namespace System.Collections
|
|||
if (mSize + addCount > AllocSize) EnsureCapacity(mSize + addCount, true);
|
||||
if (index < mSize)
|
||||
{
|
||||
Internal.MemCpy(mItems + index + addCount, mItems + index, (mSize - index) * strideof(T), alignof(T));
|
||||
Internal.MemMove(mItems + index + addCount, mItems + index, (mSize - index) * strideof(T), alignof(T));
|
||||
}
|
||||
Internal.MemCpy(mItems + index, items.Ptr, addCount * strideof(T));
|
||||
mSize += (int_cosize)addCount;
|
||||
|
@ -567,7 +638,7 @@ namespace System.Collections
|
|||
Debug.Assert((uint)index < (uint)mSize);
|
||||
if (index < mSize - 1)
|
||||
{
|
||||
Internal.MemCpy(mItems + index, mItems + index + 1, (mSize - index - 1) * strideof(T), alignof(T));
|
||||
Internal.MemMove(mItems + index, mItems + index + 1, (mSize - index - 1) * strideof(T), alignof(T));
|
||||
}
|
||||
mSize--;
|
||||
#if VERSION_LIST
|
||||
|
@ -930,6 +1001,59 @@ namespace System.Collections
|
|||
}
|
||||
}
|
||||
|
||||
extension List<T> where T : String
|
||||
{
|
||||
public bool Contains(T item, StringComparison comparison)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
for (int i = 0; i < mSize; i++)
|
||||
if (mItems[i] == null)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < mSize; i++)
|
||||
if (mItems[i].Equals(item, comparison))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int IndexOf(T item, StringComparison comparison)
|
||||
{
|
||||
for (int i = 0; i < mSize; i++)
|
||||
if (mItems[i].Equals(item, comparison))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int IndexOf(T item, int index, StringComparison comparison)
|
||||
{
|
||||
for (int i = index; i < mSize; i++)
|
||||
if (mItems[i].Equals(item, comparison))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int IndexOf(T item, int index, int count, StringComparison comparison)
|
||||
{
|
||||
for (int i = index; i < index + count; i++)
|
||||
if (mItems[i].Equals(item, comparison))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int LastIndexOf(T item, StringComparison comparison)
|
||||
{
|
||||
for (int i = mSize - 1; i >= 0; i--)
|
||||
if (mItems[i].Equals(item, comparison))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
class ListWithAlloc<T> : List<T>
|
||||
{
|
||||
IRawAllocator mAlloc;
|
||||
|
|
|
@ -18,6 +18,12 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
public static class Options
|
||||
{
|
||||
[LinkName("#AllocStackCount")]
|
||||
public static extern int32 AllocStackCount;
|
||||
}
|
||||
|
||||
[LinkName("#CallerLineNum")]
|
||||
public static extern int CallerLineNum;
|
||||
|
||||
|
@ -37,7 +43,7 @@ namespace System
|
|||
public static extern String CallerProject;
|
||||
|
||||
[LinkName("#CallerExpression")]
|
||||
public static extern String[Int32.MaxValue] CallerExpression;
|
||||
public static extern String[0x0FFFFFFF] CallerExpression;
|
||||
|
||||
[LinkName("#ProjectName")]
|
||||
public static extern String ProjectName;
|
||||
|
|
|
@ -7,6 +7,12 @@ namespace System
|
|||
{
|
||||
public static class Console
|
||||
{
|
||||
public enum CancelKind
|
||||
{
|
||||
CtrlC,
|
||||
CtrlBreak
|
||||
}
|
||||
|
||||
static Encoding InputEncoding = Encoding.ASCII;
|
||||
static Encoding OutputEncoding = Encoding.ASCII;
|
||||
|
||||
|
@ -16,6 +22,9 @@ namespace System
|
|||
static readonly ConsoleColor sOriginalForegroundColor = sForegroundColor;
|
||||
static readonly ConsoleColor sOriginalBackgroundColor = sBackgroundColor;
|
||||
|
||||
static Event<delegate void (CancelKind cancelKind, ref bool terminate)> sOnCancel ~ _.Dispose();
|
||||
static bool sCancelEventRegistered;
|
||||
|
||||
public static ConsoleColor ForegroundColor
|
||||
{
|
||||
get { return sForegroundColor; }
|
||||
|
@ -42,16 +51,57 @@ namespace System
|
|||
public uint16[2] mMaximumWindowSize;
|
||||
}
|
||||
|
||||
[CLink, CallingConvention(.Stdcall)]
|
||||
static extern int SetConsoleTextAttribute(void* hConsoleOutput, uint16 wAttributes);
|
||||
[CRepr]
|
||||
struct COORD : this(int16 X, int16 Y)
|
||||
{
|
||||
}
|
||||
|
||||
[CLink, CallingConvention(.Stdcall)]
|
||||
static extern int GetConsoleScreenBufferInfo(void* hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
|
||||
|
||||
[CLink, CallingConvention(.Stdcall)]
|
||||
static extern void* GetStdHandle(uint32 nStdHandle);
|
||||
public static ref Event<delegate void (CancelKind cancelKind, ref bool terminate)> OnCancel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!sCancelEventRegistered)
|
||||
{
|
||||
sCancelEventRegistered = true;
|
||||
#if BF_PLATFORM_WINDOWS
|
||||
SetConsoleCtrlHandler(=> ConsoleCtrlHandler, true);
|
||||
#endif
|
||||
}
|
||||
return ref sOnCancel;
|
||||
}
|
||||
}
|
||||
|
||||
#if BF_PLATFORM_WINDOWS
|
||||
[CallingConvention(.Stdcall)]
|
||||
public static Windows.IntBool ConsoleCtrlHandler(int32 ctrlType)
|
||||
{
|
||||
bool terminate = true;
|
||||
if ((ctrlType == 0) || (ctrlType == 1))
|
||||
sOnCancel((.)ctrlType, ref terminate);
|
||||
return terminate ? false : true;
|
||||
}
|
||||
|
||||
[CLink, CallingConvention(.Stdcall)]
|
||||
static extern Windows.IntBool SetConsoleTextAttribute(Windows.Handle hConsoleOutput, uint16 wAttributes);
|
||||
|
||||
[CLink, CallingConvention(.Stdcall)]
|
||||
static extern Windows.IntBool GetConsoleScreenBufferInfo(Windows.Handle hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
|
||||
|
||||
[CLink, CallingConvention(.Stdcall)]
|
||||
static extern Windows.Handle GetStdHandle(uint32 nStdHandle);
|
||||
|
||||
[CallingConvention(.Stdcall)]
|
||||
function Windows.IntBool ConsoleCtrlHandler(int32 ctrlType);
|
||||
[CLink, CallingConvention(.Stdcall)]
|
||||
static extern Windows.IntBool SetConsoleCtrlHandler(ConsoleCtrlHandler handler, Windows.IntBool addHandler);
|
||||
|
||||
[CLink, CallingConvention(.Stdcall)]
|
||||
static extern Windows.IntBool FillConsoleOutputCharacterW(Windows.Handle hConsoleOutput, char16 cCharacter, uint32 nLength, COORD dwWriteCoord, uint32* lpNumberOfCharsWritten);
|
||||
[CLink, CallingConvention(.Stdcall)]
|
||||
static extern Windows.IntBool FillConsoleOutputAttribute(Windows.Handle hConsoleOutput, uint16 wAttribute, uint32 nLength, COORD dwWriteCoord, uint32* lpNumberOfAttrsWritten);
|
||||
[CLink, CallingConvention(.Stdcall)]
|
||||
static extern Windows.IntBool SetConsoleCursorPosition(Windows.Handle hConsoleOutput, COORD dwCursorPosition);
|
||||
|
||||
public static this()
|
||||
{
|
||||
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
@ -219,6 +269,49 @@ namespace System
|
|||
#else
|
||||
Write("\x1B[{}m", ForegroundColor.AnsiCode);
|
||||
Write("\x1B[{}m", BackgroundColor.AnsiCode + 10);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
#if BF_PLATFORM_WINDOWS
|
||||
Windows.Handle hStdOut;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
uint32 count;
|
||||
uint32 cellCount;
|
||||
COORD homeCoords = .(0, 0);
|
||||
|
||||
hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
|
||||
if (hStdOut == .InvalidHandle)
|
||||
return;
|
||||
|
||||
/* Get the number of cells in the current buffer */
|
||||
if (!GetConsoleScreenBufferInfo( hStdOut, out csbi ))
|
||||
return;
|
||||
cellCount = csbi.mSize[0] * csbi.mSize[1];
|
||||
|
||||
/* Fill the entire buffer with spaces */
|
||||
if (!FillConsoleOutputCharacterW(
|
||||
hStdOut,
|
||||
' ',
|
||||
cellCount,
|
||||
homeCoords,
|
||||
&count
|
||||
)) return;
|
||||
|
||||
/* Fill the entire buffer with the current colors and attributes */
|
||||
if (!FillConsoleOutputAttribute(
|
||||
hStdOut,
|
||||
csbi.mAttributes,
|
||||
cellCount,
|
||||
homeCoords,
|
||||
&count
|
||||
)) return;
|
||||
|
||||
/* Move the cursor home */
|
||||
SetConsoleCursorPosition( hStdOut, homeCoords );
|
||||
#else
|
||||
Write("\x1B[H\x1B[J");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace System.Diagnostics
|
|||
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
|
||||
// This is the maximum number of chars 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;
|
||||
|
@ -194,7 +194,7 @@ namespace System.Diagnostics
|
|||
int lineStart = 0;
|
||||
int len = sb.Length;
|
||||
|
||||
// skip a beginning '\n' char8acter of new block if last block ended
|
||||
// skip a beginning '\n' character of new block if last block ended
|
||||
// with '\r'
|
||||
if (bLastCarriageReturn && (len > 0) && sb[0] == '\n')
|
||||
{
|
||||
|
@ -206,7 +206,7 @@ namespace System.Diagnostics
|
|||
while (currentIndex < len)
|
||||
{
|
||||
char8 ch = sb[currentIndex];
|
||||
// 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')
|
||||
{
|
||||
|
@ -214,7 +214,7 @@ namespace System.Diagnostics
|
|||
s.Append(sb, lineStart, currentIndex - lineStart);
|
||||
|
||||
lineStart = currentIndex + 1;
|
||||
// skip the "\n" char8acter following "\r" char8acter
|
||||
// skip the "\n" character following "\r" character
|
||||
if ((ch == '\r') && (lineStart < len) && (sb[lineStart] == '\n'))
|
||||
{
|
||||
lineStart++;
|
||||
|
@ -232,7 +232,7 @@ namespace System.Diagnostics
|
|||
{
|
||||
bLastCarriageReturn = true;
|
||||
}
|
||||
// Keep the rest char8acaters which can't form a new line in string builder.
|
||||
// Keep the rest characaters which can't form a new line in string builder.
|
||||
if (lineStart < len)
|
||||
{
|
||||
if (lineStart == 0)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace System.Diagnostics
|
||||
{
|
||||
class Check
|
||||
static class Check
|
||||
{
|
||||
|
||||
[Unchecked, SkipCall]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace System.Diagnostics.Contracts
|
||||
{
|
||||
class Contract
|
||||
static class Contract
|
||||
{
|
||||
public enum ContractFailureKind
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace System.Diagnostics
|
||||
{
|
||||
class Debug
|
||||
static class Debug
|
||||
{
|
||||
#if !DEBUG
|
||||
[SkipCall]
|
||||
|
@ -44,6 +44,11 @@ namespace System.Diagnostics
|
|||
Write(line.Ptr, line.Length);
|
||||
}
|
||||
|
||||
public static void Write(StringView sv)
|
||||
{
|
||||
Write(sv.[Friend]mPtr, sv.[Friend]mLength);
|
||||
}
|
||||
|
||||
public static void Write(String fmt, params Object[] args)
|
||||
{
|
||||
String str = scope String(4096);
|
||||
|
|
|
@ -136,7 +136,7 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
public void Remove(T compareDelegate, bool deleteDelegate = false) mut
|
||||
public Result<void> Remove(T compareDelegate, bool deleteDelegate = false) mut
|
||||
{
|
||||
Object data = Target;
|
||||
|
||||
|
@ -150,9 +150,7 @@ namespace System
|
|||
break;
|
||||
}
|
||||
if (idx == -1)
|
||||
{
|
||||
Runtime.FatalError("Not found");
|
||||
}
|
||||
return .Err;
|
||||
|
||||
if (deleteDelegate)
|
||||
delete list[idx];
|
||||
|
@ -177,18 +175,14 @@ namespace System
|
|||
else
|
||||
{
|
||||
T dlgMember = (T)data;
|
||||
if (Delegate.Equals(compareDelegate, dlgMember))
|
||||
{
|
||||
if (deleteDelegate)
|
||||
delete dlgMember;
|
||||
Target = null;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Runtime.FatalError("Not found");
|
||||
}
|
||||
if (!Delegate.Equals(compareDelegate, dlgMember))
|
||||
return .Err;
|
||||
if (deleteDelegate)
|
||||
delete dlgMember;
|
||||
Target = null;
|
||||
}
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
|
||||
public rettype(T) Invoke(params T p) mut
|
||||
|
|
|
@ -175,6 +175,17 @@ namespace System
|
|||
{
|
||||
char8 c = val.Ptr[i];
|
||||
|
||||
//Exponent prefix used in scientific notation. E.g. 1.2E5
|
||||
if ((c == 'e') || (c == 'E'))
|
||||
{
|
||||
//Error if there are no numbers after the prefix
|
||||
if(i == val.Length - 1)
|
||||
return .Err;
|
||||
var exponent = Try!(int32.Parse(val.Substring(i + 1)));
|
||||
result *= Math.Pow(10, (double)exponent);
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == '.')
|
||||
{
|
||||
if (decimalMultiplier != 0)
|
||||
|
|
|
@ -173,6 +173,10 @@ namespace System
|
|||
// or the memory would already be registered with the GC
|
||||
}
|
||||
|
||||
public static mixin Mark<T>(T val)
|
||||
{
|
||||
}
|
||||
|
||||
public static mixin Mark<TSizedArray, T, Size>(TSizedArray val) where Size : const int where TSizedArray : SizedArray<T, Size>
|
||||
{
|
||||
#if BF_ENABLE_REALTIME_LEAK_CHECK
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace System.Globalization
|
|||
|
||||
// cache for the invariant culture.
|
||||
// invariantInfo is constant irrespective of your current culture.
|
||||
private static volatile DateTimeFormatInfo invariantInfo;
|
||||
private static volatile DateTimeFormatInfo invariantInfo ~ delete _;
|
||||
|
||||
// an index which points to a record in Culture Data Table.
|
||||
private CultureData m_cultureData;
|
||||
|
@ -139,6 +139,8 @@ namespace System.Globalization
|
|||
List<Object> ownedObjects = new .() ~ DeleteContainerAndItems!(_);
|
||||
|
||||
public this()
|
||||
: this(CultureInfo.InvariantCulture.[Friend]m_cultureData,
|
||||
GregorianCalendar.[Friend]GetDefaultInstance())
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace System.Globalization {
|
|||
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366
|
||||
) ~ delete _;
|
||||
|
||||
private static volatile Calendar s_defaultInstance;
|
||||
private static volatile Calendar s_defaultInstance ~ delete _;
|
||||
|
||||
|
||||
#region Serialization
|
||||
|
|
|
@ -23,6 +23,10 @@ namespace System
|
|||
{
|
||||
}
|
||||
|
||||
interface ICharacter
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Consider operator constraint such as `where bool : operator T == T`", false)]
|
||||
interface IOpEquals
|
||||
{
|
||||
|
|
|
@ -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')
|
||||
{
|
||||
|
|
|
@ -243,6 +243,7 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
[AlwaysInclude]
|
||||
public static String[] CreateParamsArray()
|
||||
{
|
||||
char8* cmdLine = GetCommandLineArgs();
|
||||
|
@ -347,6 +348,7 @@ namespace System
|
|||
return strVals;
|
||||
}
|
||||
|
||||
[AlwaysInclude]
|
||||
public static void DeleteStringArray(String[] arr)
|
||||
{
|
||||
for (var str in arr)
|
||||
|
|
|
@ -24,7 +24,9 @@ namespace System
|
|||
|
||||
private static float[7] sRoundPower10Single = .(
|
||||
1E0f, 1E1f, 1E2f, 1E3f, 1E4f, 1E5f, 1E6f);
|
||||
|
||||
|
||||
private static float sMachineEpsilonFloat = GetMachineEpsilonFloat();
|
||||
|
||||
public const double PI_d = 3.14159265358979323846;
|
||||
public const double E_d = 2.7182818284590452354;
|
||||
public const float PI_f = 3.14159265358979323846f;
|
||||
|
@ -48,6 +50,33 @@ namespace System
|
|||
public static extern float Floor(float f);
|
||||
public static extern double Floor(double d);
|
||||
|
||||
public static bool WithinEpsilon(float a, float b)
|
||||
{
|
||||
return Math.Abs(a - b) < sMachineEpsilonFloat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the current machine's Epsilon for the float data type.
|
||||
/// (That is, the largest float, e, where e == 0.0f is true.)
|
||||
/// </summary>
|
||||
private static float GetMachineEpsilonFloat()
|
||||
{
|
||||
float machineEpsilon = 1.0f;
|
||||
float comparison;
|
||||
|
||||
/* Keep halving the working value of machineEpsilon until we get a number that
|
||||
* when added to 1.0f will still evaluate as equal to 1.0f.
|
||||
*/
|
||||
repeat
|
||||
{
|
||||
machineEpsilon *= 0.5f;
|
||||
comparison = 1.0f + machineEpsilon;
|
||||
}
|
||||
while (comparison > 1.0f);
|
||||
|
||||
return machineEpsilon;
|
||||
}
|
||||
|
||||
private static float InternalRound(float value, int32 digits, MidpointRounding mode)
|
||||
{
|
||||
if (Abs(value) < cSingleRoundLimit)
|
||||
|
@ -476,5 +505,125 @@ namespace System
|
|||
{
|
||||
return ((val) + (align - 1)) & ~(align - 1);
|
||||
}
|
||||
|
||||
/// Interpolates between two values using a cubic equation.
|
||||
/// @param name Source value.
|
||||
/// @param name Source value.
|
||||
/// @param name Weighting value.
|
||||
/// @returns Interpolated value.
|
||||
public static float SmoothStep(float value1, float value2, float amount)
|
||||
{
|
||||
/* It is expected that 0 < amount < 1.
|
||||
* If amount < 0, return value1.
|
||||
* If amount > 1, return value2.
|
||||
*/
|
||||
float result = Clamp(amount, 0f, 1f);
|
||||
result = Hermite(value1, 0f, value2, 0f, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Performs a Hermite spline interpolation.
|
||||
/// @param value1 Source position.
|
||||
/// @param tangent1 Source tangent.
|
||||
/// @param value2 Source position.
|
||||
/// @param tangent2 Source tangent.
|
||||
/// @param amount Weighting factor.
|
||||
/// @returns The result of the Hermite spline interpolation.
|
||||
public static float Hermite(
|
||||
float value1,
|
||||
float tangent1,
|
||||
float value2,
|
||||
float tangent2,
|
||||
float amount
|
||||
) {
|
||||
/* All transformed to double not to lose precision
|
||||
* Otherwise, for high numbers of param:amount the result is NaN instead
|
||||
* of Infinity.
|
||||
*/
|
||||
double v1 = value1, v2 = value2, t1 = tangent1, t2 = tangent2, s = amount;
|
||||
double result;
|
||||
double sCubed = s * s * s;
|
||||
double sSquared = s * s;
|
||||
|
||||
if (WithinEpsilon(amount, 0f))
|
||||
{
|
||||
result = value1;
|
||||
}
|
||||
else if (WithinEpsilon(amount, 1f))
|
||||
{
|
||||
result = value2;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (
|
||||
((2 * v1 - 2 * v2 + t2 + t1) * sCubed) +
|
||||
((3 * v2 - 3 * v1 - 2 * t1 - t2) * sSquared) +
|
||||
(t1 * s) +
|
||||
v1
|
||||
);
|
||||
}
|
||||
|
||||
return (float) result;
|
||||
}
|
||||
|
||||
/// Returns the Cartesian coordinate for one axis of a point that is defined by a
|
||||
/// given triangle and two normalized barycentric (areal) coordinates.
|
||||
/// <param name="value1">
|
||||
/// The coordinate on one axis of vertex 1 of the defining triangle.
|
||||
/// </param>
|
||||
/// <param name="value2">
|
||||
/// The coordinate on the same axis of vertex 2 of the defining triangle.
|
||||
/// </param>
|
||||
/// <param name="value3">
|
||||
/// The coordinate on the same axis of vertex 3 of the defining triangle.
|
||||
/// </param>
|
||||
/// <param name="amount1">
|
||||
/// The normalized barycentric (areal) coordinate b2, equal to the weighting factor
|
||||
/// for vertex 2, the coordinate of which is specified in value2.
|
||||
/// </param>
|
||||
/// @param amount2
|
||||
/// The normalized barycentric (areal) coordinate b3, equal to the weighting factor
|
||||
/// for vertex 3, the coordinate of which is specified in value3.
|
||||
/// </param>
|
||||
/// @returns Cartesian coordinate of the specified point with respect to the axis being used.
|
||||
public static float Barycentric(
|
||||
float value1,
|
||||
float value2,
|
||||
float value3,
|
||||
float amount1,
|
||||
float amount2
|
||||
) {
|
||||
return value1 + (value2 - value1) * amount1 + (value3 - value1) * amount2;
|
||||
}
|
||||
|
||||
/// Performs a Catmull-Rom interpolation using the specified positions.
|
||||
/// @param value1 The first position in the interpolation.
|
||||
/// @param value2">The second position in the interpolation.
|
||||
/// @param value3">The third position in the interpolation.
|
||||
/// @param value4">The fourth position in the interpolation.
|
||||
/// @param name="amount">Weighting factor.
|
||||
/// @returns A position that is the result of the Catmull-Rom interpolation.
|
||||
public static float CatmullRom(
|
||||
float value1,
|
||||
float value2,
|
||||
float value3,
|
||||
float value4,
|
||||
float amount
|
||||
) {
|
||||
/* Using formula from http://www.mvps.org/directx/articles/catmull/
|
||||
* Internally using doubles not to lose precision.
|
||||
*/
|
||||
double amountSquared = amount * amount;
|
||||
double amountCubed = amountSquared * amount;
|
||||
return (float) (
|
||||
0.5 *
|
||||
(
|
||||
((2.0 * value2 + (value3 - value1) * amount) +
|
||||
((2.0 * value1 - 5.0 * value2 + 4.0 * value3 - value4) * amountSquared) +
|
||||
(3.0 * value2 - value1 - 3.0 * value3 + value4) * amountCubed)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace System.Net
|
|||
{
|
||||
class Socket
|
||||
{
|
||||
const uint16 WINSOCK_VERSION = 0x0202;
|
||||
const int32 WSAENETRESET = 10052;
|
||||
const int32 WSAECONNABORTED = 10053;
|
||||
const int32 WSAECONNRESET = 10054;
|
||||
|
@ -169,12 +170,22 @@ namespace System.Net
|
|||
#if BF_PLATFORM_WINDOWS
|
||||
[Import("wsock32.lib"), CLink, CallingConvention(.Stdcall)]
|
||||
static extern int32 WSAStartup(uint16 versionRequired, WSAData* wsaData);
|
||||
|
||||
[Import("wsock32.lib"), CLink, CallingConvention(.Stdcall)]
|
||||
static extern int32 WSACleanup();
|
||||
|
||||
[Import("wsock32.lib"), CLink, CallingConvention(.Stdcall)]
|
||||
static extern int32 WSAGetLastError();
|
||||
#elif BF_PLATFORM_LINUX
|
||||
[LinkName("__errno_location")]
|
||||
static extern int32* _errno();
|
||||
#elif BF_PLATFORM_MACOS
|
||||
[LinkName("__error")]
|
||||
static extern int32* _errno();
|
||||
#else
|
||||
[CLink]
|
||||
static int32 errno;
|
||||
static int32* _errno() => &errno;
|
||||
#endif
|
||||
|
||||
[CLink, CallingConvention(.Stdcall)]
|
||||
|
@ -230,11 +241,22 @@ namespace System.Net
|
|||
#endif
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
public static int32 Init(uint16 versionRequired = WINSOCK_VERSION)
|
||||
{
|
||||
#if BF_PLATFORM_WINDOWS
|
||||
WSAData wsaData = default;
|
||||
WSAStartup(0x202, &wsaData);
|
||||
return WSAStartup(versionRequired, &wsaData);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static int32 Uninit()
|
||||
{
|
||||
#if BF_PLATFORM_WINDOWS
|
||||
return WSACleanup();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -243,7 +265,7 @@ namespace System.Net
|
|||
#if BF_PLATFORM_WINDOWS
|
||||
return WSAGetLastError();
|
||||
#else
|
||||
return errno;
|
||||
return *_errno();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -2675,7 +2675,7 @@ namespace System
|
|||
return;
|
||||
|
||||
int i = sb.Length + (end - start);
|
||||
sb.Length = i;
|
||||
sb.PrepareBuffer(i);
|
||||
|
||||
var end;
|
||||
var start;
|
||||
|
|
|
@ -271,6 +271,7 @@ namespace System
|
|||
CreateAlways,
|
||||
CreateIfNotExists,
|
||||
OpenExisting,
|
||||
OpenAlways,
|
||||
};
|
||||
|
||||
public enum BfpFileCreateFlags : int32
|
||||
|
@ -337,6 +338,8 @@ namespace System
|
|||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern BfpFile* BfpFile_GetStd(BfpFileStdKind kind, BfpFileResult* outResult);
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern int BfpFile_GetSystemHandle(BfpFile* file);
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern void BfpFile_Release(BfpFile* file);
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern int BfpFile_Write(BfpFile* file, void* buffer, int size, int timeoutMS, BfpFileResult* outResult);
|
||||
|
@ -349,7 +352,7 @@ namespace System
|
|||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern int64 BfpFile_Seek(BfpFile* file, int64 offset, BfpFileSeekKind seekKind);
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern void BfpFile_Truncate(BfpFile* file);
|
||||
public static extern void BfpFile_Truncate(BfpFile* file, BfpFileResult* outResult);
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern BfpTimeStamp BfpFile_GetTime_LastWrite(char8* path);
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
|
@ -410,7 +413,8 @@ namespace System
|
|||
AppData_LocalLow,
|
||||
AppData_Roaming,
|
||||
Programs,
|
||||
Programs_Common
|
||||
Programs_Common,
|
||||
Documents
|
||||
}
|
||||
|
||||
public static Result<void, Platform.Result> GetStrHelper(String outStr, delegate void (char8* outPtr, int32* outSize, Result* outResult) func)
|
||||
|
|
468
BeefLibs/corlib/src/Range.bf
Normal file
468
BeefLibs/corlib/src/Range.bf
Normal file
|
@ -0,0 +1,468 @@
|
|||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System
|
||||
{
|
||||
interface RangeExpression
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
enum Index
|
||||
{
|
||||
case FromFront(int offset);
|
||||
case FromEnd(int offset);
|
||||
|
||||
public override void ToString(String strBuffer)
|
||||
{
|
||||
switch (this)
|
||||
{
|
||||
case .FromFront(let offset):
|
||||
offset.ToString(strBuffer);
|
||||
case .FromEnd(let offset):
|
||||
strBuffer.Append('^');
|
||||
offset.ToString(strBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Range : RangeExpression, IEnumerable<int>
|
||||
{
|
||||
protected int mStart;
|
||||
protected int mEnd;
|
||||
|
||||
public this()
|
||||
{
|
||||
mStart = 0;
|
||||
mEnd = 0;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public this(int start, int end)
|
||||
{
|
||||
Debug.Assert(end >= start);
|
||||
mStart = start;
|
||||
mEnd = end;
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mEnd - mStart;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
set mut
|
||||
{
|
||||
mEnd = mStart + value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Start
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mStart;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
set mut
|
||||
{
|
||||
mStart = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int End
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mEnd;
|
||||
}
|
||||
|
||||
set mut
|
||||
{
|
||||
mEnd = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEmpty
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mEnd == mStart;
|
||||
}
|
||||
}
|
||||
|
||||
public ReverseEnumerator Reversed
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return ReverseEnumerator(mEnd - 1, mStart);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(int idx)
|
||||
{
|
||||
return (idx >= mStart) && (idx < mEnd);
|
||||
}
|
||||
|
||||
public bool Contains(Range val)
|
||||
{
|
||||
return (val.[Friend]mStart >= mStart) && (val.[Friend]mEnd <= mEnd);
|
||||
}
|
||||
|
||||
public bool Contains(ClosedRange val)
|
||||
{
|
||||
return (val.[Friend]mStart >= mStart) && (val.[Friend]mEnd <= mEnd - 1);
|
||||
}
|
||||
|
||||
public void Clear() mut
|
||||
{
|
||||
mStart = 0;
|
||||
mEnd = 0;
|
||||
}
|
||||
|
||||
public static operator IndexRange(Range list)
|
||||
{
|
||||
return .(.FromFront(list.mStart), .FromFront(list.mEnd), false);
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return Enumerator(this);
|
||||
}
|
||||
|
||||
public override void ToString(String strBuffer)
|
||||
{
|
||||
strBuffer.AppendF($"{mStart}..<{mEnd}");
|
||||
}
|
||||
|
||||
public struct Enumerator : IEnumerator<int>
|
||||
{
|
||||
private int mEnd;
|
||||
private int mIndex;
|
||||
|
||||
[Inline]
|
||||
public this(Range range)
|
||||
{
|
||||
mIndex = range.mStart - 1;
|
||||
mEnd = range.mEnd;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public ref int Index
|
||||
{
|
||||
get mut
|
||||
{
|
||||
return ref mIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public int End => mEnd;
|
||||
|
||||
[Inline]
|
||||
public Result<int> GetNext() mut
|
||||
{
|
||||
if (mIndex + 1 >= mEnd)
|
||||
return .Err;
|
||||
return ++mIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public struct ReverseEnumerator : IEnumerator<int>
|
||||
{
|
||||
private int mEnd;
|
||||
private int mIndex;
|
||||
|
||||
[Inline]
|
||||
public this(int start, int end)
|
||||
{
|
||||
mIndex = start + 1;
|
||||
mEnd = end;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public ref int Index
|
||||
{
|
||||
get mut
|
||||
{
|
||||
return ref mIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public int End => mEnd;
|
||||
|
||||
[Inline]
|
||||
public Result<int> GetNext() mut
|
||||
{
|
||||
if (mIndex <= mEnd)
|
||||
return .Err;
|
||||
return --mIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct IndexRange : RangeExpression
|
||||
{
|
||||
protected Index mStart;
|
||||
protected Index mEnd;
|
||||
protected bool mIsClosed;
|
||||
|
||||
public this()
|
||||
{
|
||||
this = default;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public this(Index start, Index end, bool isClosed=true)
|
||||
{
|
||||
mStart = start;
|
||||
mEnd = end;
|
||||
mIsClosed = isClosed;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public this(int start, Index end, bool isClosed=true)
|
||||
{
|
||||
mStart = .FromFront(start);
|
||||
mEnd = end;
|
||||
mIsClosed = isClosed;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public this(Index start, int end, bool isClosed=true)
|
||||
{
|
||||
mStart = start;
|
||||
mEnd = .FromFront(end);
|
||||
mIsClosed = isClosed;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public this(int start, int end, bool isClosed=true)
|
||||
{
|
||||
mStart = .FromFront(start);
|
||||
mEnd = .FromFront(end);
|
||||
mIsClosed = isClosed;
|
||||
}
|
||||
|
||||
public Index Start
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mStart;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
set mut
|
||||
{
|
||||
mStart = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Index End
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mEnd;
|
||||
}
|
||||
|
||||
set mut
|
||||
{
|
||||
mEnd = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsClosed
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mIsClosed;
|
||||
}
|
||||
|
||||
set mut
|
||||
{
|
||||
mIsClosed = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ToString(String strBuffer)
|
||||
{
|
||||
mStart.ToString(strBuffer);
|
||||
if (mIsClosed)
|
||||
strBuffer.Append("...");
|
||||
else
|
||||
strBuffer.Append("..<");
|
||||
mEnd.ToString(strBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
struct ClosedRange : RangeExpression, IEnumerable<int>
|
||||
{
|
||||
protected int mStart;
|
||||
protected int mEnd;
|
||||
|
||||
public this()
|
||||
{
|
||||
mStart = 0;
|
||||
mEnd = 0;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public this(int start, int end)
|
||||
{
|
||||
Debug.Assert(end >= start);
|
||||
mStart = start;
|
||||
mEnd = end;
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mEnd - mStart;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
set mut
|
||||
{
|
||||
mEnd = mStart + value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Start
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mStart;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
set mut
|
||||
{
|
||||
mStart = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int End
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mEnd;
|
||||
}
|
||||
|
||||
set mut
|
||||
{
|
||||
mEnd = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEmpty
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mEnd == mStart;
|
||||
}
|
||||
}
|
||||
|
||||
public Range.ReverseEnumerator Reversed
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return Range.ReverseEnumerator(mEnd, mStart);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(int idx)
|
||||
{
|
||||
return (idx >= mStart) && (idx <= mEnd);
|
||||
}
|
||||
|
||||
public bool Contains(Range val)
|
||||
{
|
||||
return (val.[Friend]mStart >= mStart) && (val.[Friend]mEnd - 1 <= mEnd);
|
||||
}
|
||||
|
||||
public bool Contains(ClosedRange val)
|
||||
{
|
||||
return (val.[Friend]mStart >= mStart) && (val.[Friend]mEnd <= mEnd);
|
||||
}
|
||||
|
||||
public void Clear() mut
|
||||
{
|
||||
mStart = 0;
|
||||
mEnd = 0;
|
||||
}
|
||||
|
||||
public static operator IndexRange(ClosedRange list)
|
||||
{
|
||||
return .(.FromFront(list.mStart), .FromFront(list.mEnd), true);
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return Enumerator(this);
|
||||
}
|
||||
|
||||
public override void ToString(String strBuffer)
|
||||
{
|
||||
strBuffer.AppendF($"{mStart}...{mEnd}");
|
||||
}
|
||||
|
||||
public struct Enumerator : IEnumerator<int>
|
||||
{
|
||||
private int mEnd;
|
||||
private int mIndex;
|
||||
|
||||
[Inline]
|
||||
public this(ClosedRange range)
|
||||
{
|
||||
mIndex = range.mStart - 1;
|
||||
mEnd = range.mEnd;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public ref int Index
|
||||
{
|
||||
get mut
|
||||
{
|
||||
return ref mIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public int End => mEnd;
|
||||
|
||||
[Inline]
|
||||
public Result<int> GetNext() mut
|
||||
{
|
||||
if (mIndex >= mEnd)
|
||||
return .Err;
|
||||
return ++mIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -92,6 +92,9 @@ namespace System.Reflection
|
|||
.Double:
|
||||
let attrData = Decode!<int64>(data);
|
||||
args[argIdx] = scope:AttrBlock box attrData;
|
||||
case (TypeCode)51: //BfConstType_TypeOf
|
||||
let argTypeId = Decode!<int32>(data);
|
||||
args[argIdx] = Type.[Friend]GetType((.)argTypeId);
|
||||
case (TypeCode)255:
|
||||
let stringId = Decode!<int32>(data);
|
||||
String str = String.[Friend]sIdStringLiterals[stringId];
|
||||
|
|
|
@ -29,8 +29,8 @@ namespace System.Reflection
|
|||
get
|
||||
{
|
||||
if (Compiler.IsComptime)
|
||||
Type.[Friend]Comptime_Method_GetName(mNativeMethodInstance);
|
||||
return "";
|
||||
return Type.[Friend]Comptime_Method_GetName(mNativeMethodInstance);
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
public int ParamCount
|
||||
|
|
|
@ -20,53 +20,13 @@ namespace System.Reflection
|
|||
mFieldData = fieldData;
|
||||
}
|
||||
|
||||
public int32 MemberOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
return (int32)mFieldData.mData;
|
||||
}
|
||||
}
|
||||
|
||||
public Type FieldType
|
||||
{
|
||||
get
|
||||
{
|
||||
return Type.[Friend]GetType(mFieldData.mFieldTypeId);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsConst
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFieldData.mFlags.HasFlag(.Const);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsStatic
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFieldData.mFlags.HasFlag(.Static);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsInstanceField
|
||||
{
|
||||
get
|
||||
{
|
||||
return !mFieldData.mFlags.HasFlag(.Static) && !mFieldData.mFlags.HasFlag(.Const);
|
||||
}
|
||||
}
|
||||
|
||||
public StringView Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFieldData.mName;
|
||||
}
|
||||
}
|
||||
public TypeInstance DeclaringType => mTypeInstance;
|
||||
public int32 MemberOffset => (int32)mFieldData.mData;
|
||||
public Type FieldType => Type.[Friend]GetType(mFieldData.mFieldTypeId);
|
||||
public bool IsConst => mFieldData.mFlags.HasFlag(.Const);
|
||||
public bool IsStatic => mFieldData.mFlags.HasFlag(.Static);
|
||||
public bool IsInstanceField => !mFieldData.mFlags.HasFlag(.Static) && !mFieldData.mFlags.HasFlag(.Const);
|
||||
public StringView Name => mFieldData.mName;
|
||||
|
||||
public Result<void, Error> SetValue(Object obj, Object value)
|
||||
{
|
||||
|
@ -525,7 +485,15 @@ namespace System.Reflection
|
|||
{
|
||||
mIdx++;
|
||||
if (mIdx == mTypeInstance.[Friend]mFieldDataCount)
|
||||
return false;
|
||||
{
|
||||
if (mBindingFlags.HasFlag(.DeclaredOnly))
|
||||
return false;
|
||||
if (mTypeInstance.[Friend]mBaseType == 0)
|
||||
return false;
|
||||
mTypeInstance = Type.[Friend]GetType(mTypeInstance.[Friend]mBaseType) as TypeInstance;
|
||||
mIdx = -1;
|
||||
continue;
|
||||
}
|
||||
var fieldData = &mTypeInstance.[Friend]mFieldDataPtr[mIdx];
|
||||
bool matches = (mBindingFlags.HasFlag(BindingFlags.Static) && (fieldData.mFlags.HasFlag(FieldFlags.Static)));
|
||||
matches |= (mBindingFlags.HasFlag(BindingFlags.Instance) && (!fieldData.mFlags.HasFlag(FieldFlags.Static)));
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace System.Reflection
|
|||
mMethodData = methodData;
|
||||
}
|
||||
|
||||
public TypeInstance DeclaringType => mTypeInstance;
|
||||
public bool IsInitialized => mMethodData != null;
|
||||
public StringView Name => mMethodData.[Friend]mName;
|
||||
public int ParamCount => mMethodData.[Friend]mParamCount;
|
||||
|
@ -37,11 +38,22 @@ namespace System.Reflection
|
|||
return mMethodData.mParamData[paramIdx].mName;
|
||||
}
|
||||
|
||||
public Result<T> GetParamCustomAttribute<T>(int paramIdx) where T : Attribute
|
||||
{
|
||||
Debug.Assert((uint)paramIdx < (uint)mMethodData.mParamCount);
|
||||
return mTypeInstance.[Friend]GetCustomAttribute<T>(mMethodData.mParamData[paramIdx].mCustomAttributesIdx);
|
||||
}
|
||||
|
||||
public Result<T> GetCustomAttribute<T>() where T : Attribute
|
||||
{
|
||||
return mTypeInstance.[Friend]GetCustomAttribute<T>(mMethodData.mCustomAttributesIdx);
|
||||
}
|
||||
|
||||
public Result<T> GetReturnCustomAttribute<T>() where T : Attribute
|
||||
{
|
||||
return mTypeInstance.[Friend]GetCustomAttribute<T>(mMethodData.mReturnCustomAttributesIdx);
|
||||
}
|
||||
|
||||
public enum CallError
|
||||
{
|
||||
case None;
|
||||
|
@ -777,7 +789,15 @@ namespace System.Reflection
|
|||
{
|
||||
mIdx++;
|
||||
if (mIdx == mTypeInstance.[Friend]mMethodDataCount)
|
||||
return false;
|
||||
{
|
||||
if (mBindingFlags.HasFlag(.DeclaredOnly))
|
||||
return false;
|
||||
if (mTypeInstance.[Friend]mBaseType == 0)
|
||||
return false;
|
||||
mTypeInstance = Type.[Friend]GetType(mTypeInstance.[Friend]mBaseType) as TypeInstance;
|
||||
mIdx = -1;
|
||||
continue;
|
||||
}
|
||||
var methodData = &mTypeInstance.[Friend]mMethodDataPtr[mIdx];
|
||||
bool matches = (mBindingFlags.HasFlag(BindingFlags.Static) && (methodData.mFlags.HasFlag(.Static)));
|
||||
matches |= (mBindingFlags.HasFlag(BindingFlags.Instance) && (!methodData.mFlags.HasFlag(.Static)));
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace System
|
|||
if (matched.[Friend]mMethodData != null)
|
||||
return .Err(.MultipleResults);
|
||||
else
|
||||
matched = methodInfo;
|
||||
matched = methodInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,26 @@ namespace System
|
|||
return .Ok(matched);
|
||||
}
|
||||
|
||||
[Comptime]
|
||||
public virtual Result<ComptimeMethodInfo, MethodError> GetMethod(StringView methodName, BindingFlags bindingFlags = cDefaultLookup)
|
||||
{
|
||||
ComptimeMethodInfo matched = default;
|
||||
for (let methodInfo in ComptimeMethodInfo.Enumerator(this as TypeInstance, bindingFlags))
|
||||
{
|
||||
if (methodInfo.Name == methodName)
|
||||
{
|
||||
if (matched.mNativeMethodInstance != 0)
|
||||
return .Err(.MultipleResults);
|
||||
else
|
||||
matched = methodInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (matched.mNativeMethodInstance == 0)
|
||||
return .Err(.NoResults);
|
||||
return .Ok(matched);
|
||||
}
|
||||
|
||||
public virtual Result<MethodInfo, MethodError> GetMethod(int methodIdx)
|
||||
{
|
||||
return .Err(.NoResults);
|
||||
|
@ -123,7 +143,10 @@ namespace System.Reflection
|
|||
let objType = typeof(Object) as TypeInstance;
|
||||
|
||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||
obj = Internal.Dbg_ObjectAlloc(mTypeClassVData, mInstSize, mInstAlign, 1);
|
||||
int32 stackCount = Compiler.Options.AllocStackCount;
|
||||
if (mAllocStackCountOverride != 0)
|
||||
stackCount = mAllocStackCountOverride;
|
||||
obj = Internal.Dbg_ObjectAlloc(mTypeClassVData, mInstSize, mInstAlign, stackCount);
|
||||
#else
|
||||
void* mem = new [Align(16)] uint8[mInstSize]* (?);
|
||||
obj = Internal.UnsafeCastToObject(mem);
|
||||
|
|
|
@ -20,22 +20,26 @@ namespace System
|
|||
|
||||
public T Value
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return Unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public static implicit operator Result<T>(T value)
|
||||
{
|
||||
return .Ok(value);
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public static implicit operator T(Result<T> result)
|
||||
{
|
||||
return result.Unwrap();
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public void IgnoreError()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ using System.Threading;
|
|||
|
||||
namespace System
|
||||
{
|
||||
[StaticInitPriority(100)]
|
||||
class Runtime
|
||||
[StaticInitPriority(101)]
|
||||
static class Runtime
|
||||
{
|
||||
const int32 cVersion = 8;
|
||||
|
||||
|
@ -102,7 +102,7 @@ namespace System
|
|||
function void* (int size) mAlloc;
|
||||
function void (void* ptr) mFree;
|
||||
function void (Object obj) mObject_Delete;
|
||||
function void (Object obj, String str) mObject_ToString;
|
||||
void* mUnused0;
|
||||
function Type (Object obj) mObject_GetType;
|
||||
function void (Object obj) mObject_GCMarkMembers;
|
||||
function Object (Object obj, int32 typeId) mObject_DynamicCastToTypeId;
|
||||
|
@ -141,13 +141,6 @@ namespace System
|
|||
delete obj;
|
||||
}
|
||||
|
||||
static void Object_ToString(Object obj, String str)
|
||||
{
|
||||
#if BF_DBG_RUNTIME
|
||||
obj.ToString(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
static Type Object_GetType(Object obj)
|
||||
{
|
||||
#if BF_DBG_RUNTIME
|
||||
|
@ -241,7 +234,6 @@ namespace System
|
|||
mAlloc = => Alloc;
|
||||
mFree = => Free;
|
||||
mObject_Delete = => Object_Delete;
|
||||
mObject_ToString = => Object_ToString;
|
||||
mObject_GetType = => Object_GetType;
|
||||
mObject_GCMarkMembers = => Object_GCMarkMembers;
|
||||
mObject_DynamicCastToTypeId = => Object_DynamicCastToTypeId;
|
||||
|
|
|
@ -1,5 +1,35 @@
|
|||
namespace System.Security.Cryptography
|
||||
{
|
||||
struct HashEncode
|
||||
{
|
||||
// Only 63 chars - skip zero
|
||||
const char8[?] cHash64bToChar = .( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
|
||||
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
|
||||
'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_' );
|
||||
public static void HashEncode64(uint64 val, String outStr)
|
||||
{
|
||||
var val;
|
||||
if ((int64)val < 0)
|
||||
{
|
||||
uint64 flippedNum = (uint64)-(int64)val;
|
||||
// Only flip if the encoded result would actually be shorter
|
||||
if (flippedNum <= 0x00FFFFFFFFFFFFFFL)
|
||||
{
|
||||
val = flippedNum;
|
||||
outStr.Append('_');
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
int charIdx = (int)((val >> (i * 6)) & 0x3F) - 1;
|
||||
if (charIdx != -1)
|
||||
outStr.Append(cHash64bToChar[charIdx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MD5Hash
|
||||
{
|
||||
public uint8[16] mHash;
|
||||
|
@ -50,6 +80,14 @@ namespace System.Security.Cryptography
|
|||
val.ToString(strBuffer, "X2", null);
|
||||
}
|
||||
}
|
||||
|
||||
public void Encode(String outStr)
|
||||
{
|
||||
#unwarn
|
||||
HashEncode.HashEncode64(((uint64*)&mHash)[0], outStr);
|
||||
#unwarn
|
||||
HashEncode.HashEncode64(((uint64*)&mHash)[1], outStr);
|
||||
}
|
||||
}
|
||||
|
||||
class MD5
|
||||
|
|
|
@ -16,18 +16,35 @@ namespace System
|
|||
|
||||
public this(T[] array)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
this = default;
|
||||
return;
|
||||
}
|
||||
mPtr = &array.[Friend]GetRef(0);
|
||||
mLength = array.[Friend]mLength;
|
||||
}
|
||||
|
||||
public this(T[] array, int index)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
Debug.Assert(index == 0);
|
||||
this = default;
|
||||
return;
|
||||
}
|
||||
mPtr = &array[index];
|
||||
mLength = array.[Friend]mLength - index;
|
||||
}
|
||||
|
||||
public this(T[] array, int index, int length)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
Debug.Assert(index == 0 && length == 0);
|
||||
this = default;
|
||||
return;
|
||||
}
|
||||
if (length == 0)
|
||||
mPtr = null;
|
||||
else
|
||||
|
@ -110,13 +127,95 @@ namespace System
|
|||
|
||||
public ref T this[int index]
|
||||
{
|
||||
[Inline]
|
||||
[Checked]
|
||||
get
|
||||
{
|
||||
Runtime.Assert((uint)index < (uint)mLength);
|
||||
return ref mPtr[index];
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
get
|
||||
{
|
||||
return ref mPtr[index];
|
||||
}
|
||||
}
|
||||
|
||||
public ref T this[Index index]
|
||||
{
|
||||
[Checked]
|
||||
get
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mLength - offset;
|
||||
}
|
||||
Runtime.Assert((uint)idx < (uint)mLength);
|
||||
return ref mPtr[idx];
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
get
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mLength - offset;
|
||||
}
|
||||
return ref mPtr[idx];
|
||||
}
|
||||
}
|
||||
|
||||
public Span<T> this[IndexRange range]
|
||||
{
|
||||
#if !DEBUG
|
||||
[Inline]
|
||||
#endif
|
||||
get
|
||||
{
|
||||
T* start;
|
||||
switch (range.[Friend]mStart)
|
||||
{
|
||||
case .FromFront(let offset):
|
||||
Debug.Assert((uint)offset <= (uint)mLength);
|
||||
start = mPtr + offset;
|
||||
case .FromEnd(let offset):
|
||||
Debug.Assert((uint)offset <= (uint)mLength);
|
||||
start = mPtr + mLength - offset;
|
||||
}
|
||||
T* end;
|
||||
if (range.[Friend]mIsClosed)
|
||||
{
|
||||
switch (range.[Friend]mEnd)
|
||||
{
|
||||
case .FromFront(let offset):
|
||||
Debug.Assert((uint)offset < (uint)mLength);
|
||||
end = mPtr + offset + 1;
|
||||
case .FromEnd(let offset):
|
||||
Debug.Assert((uint)(offset - 1) <= (uint)mLength);
|
||||
end = mPtr + mLength - offset + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (range.[Friend]mEnd)
|
||||
{
|
||||
case .FromFront(let offset):
|
||||
Debug.Assert((uint)offset <= (uint)mLength);
|
||||
end = mPtr + offset;
|
||||
case .FromEnd(let offset):
|
||||
Debug.Assert((uint)offset <= (uint)mLength);
|
||||
end = mPtr + mLength - offset;
|
||||
}
|
||||
}
|
||||
|
||||
return .(start, end - start);
|
||||
}
|
||||
}
|
||||
|
||||
public Span<T> Slice(int index)
|
||||
{
|
||||
Debug.Assert((uint)index <= (uint)mLength);
|
||||
|
@ -200,6 +299,8 @@ namespace System
|
|||
return Enumerator(this);
|
||||
}
|
||||
|
||||
public ReverseEnumerator Reversed => ReverseEnumerator(this);
|
||||
|
||||
public override void ToString(String strBuffer)
|
||||
{
|
||||
strBuffer.Append("(");
|
||||
|
@ -281,6 +382,95 @@ namespace System
|
|||
}
|
||||
|
||||
|
||||
public Result<T> GetNext() mut
|
||||
{
|
||||
if (!MoveNext())
|
||||
return .Err;
|
||||
return Current;
|
||||
}
|
||||
|
||||
public Result<T*> GetNextRef() mut
|
||||
{
|
||||
if (!MoveNext())
|
||||
return .Err;
|
||||
return &CurrentRef;
|
||||
}
|
||||
}
|
||||
|
||||
public struct ReverseEnumerator : IEnumerator<T>, IRefEnumerator<T*>
|
||||
{
|
||||
private Span<T> mList;
|
||||
private int mIndex;
|
||||
private T* mCurrent;
|
||||
|
||||
public this(Span<T> list)
|
||||
{
|
||||
mList = list;
|
||||
mIndex = list.mLength - 1;
|
||||
mCurrent = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public bool MoveNext() mut
|
||||
{
|
||||
if (mIndex >= 0)
|
||||
{
|
||||
mCurrent = &mList.mPtr[mIndex];
|
||||
mIndex--;
|
||||
return true;
|
||||
}
|
||||
return MoveNextRare();
|
||||
}
|
||||
|
||||
private bool MoveNextRare() mut
|
||||
{
|
||||
mIndex = mList.mLength + 1;
|
||||
mCurrent = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public T Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return *mCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
public ref T CurrentRef
|
||||
{
|
||||
get
|
||||
{
|
||||
return ref *mCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
public int Index
|
||||
{
|
||||
get
|
||||
{
|
||||
return mIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return mList.mLength;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset() mut
|
||||
{
|
||||
mIndex = 0;
|
||||
mCurrent = null;
|
||||
}
|
||||
|
||||
|
||||
public Result<T> GetNext() mut
|
||||
{
|
||||
if (!MoveNext())
|
||||
|
|
|
@ -329,7 +329,7 @@ namespace System
|
|||
|
||||
set
|
||||
{
|
||||
Debug.Assert((uint)mLength <= (uint)value);
|
||||
Debug.Assert((uint)value <= (uint)mLength);
|
||||
mLength = (int_strsize)value;
|
||||
}
|
||||
}
|
||||
|
@ -1010,17 +1010,95 @@ namespace System
|
|||
|
||||
public ref char8 this[int index]
|
||||
{
|
||||
[Checked]
|
||||
get
|
||||
{
|
||||
Debug.Assert((uint)index < (uint)mLength);
|
||||
return ref Ptr[index];
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
get
|
||||
{
|
||||
return ref Ptr[index];
|
||||
}
|
||||
|
||||
[Checked]
|
||||
set
|
||||
{
|
||||
Debug.Assert((uint)index < (uint)mLength);
|
||||
Ptr[index] = value;
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
set
|
||||
{
|
||||
Ptr[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ref char8 this[Index index]
|
||||
{
|
||||
[Checked]
|
||||
get
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mLength - offset;
|
||||
}
|
||||
Debug.Assert((uint)idx < (uint)mLength);
|
||||
return ref Ptr[idx];
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
get
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mLength - offset;
|
||||
}
|
||||
return ref Ptr[idx];
|
||||
}
|
||||
|
||||
[Checked]
|
||||
set
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mLength - offset;
|
||||
}
|
||||
Debug.Assert((uint)idx < (uint)mLength);
|
||||
Ptr[idx] = value;
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
set
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mLength - offset;
|
||||
}
|
||||
Ptr[idx] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public StringView this[IndexRange range]
|
||||
{
|
||||
#if !DEBUG
|
||||
[Inline]
|
||||
#endif
|
||||
get
|
||||
{
|
||||
return StringView(Ptr, Length)[range];
|
||||
}
|
||||
}
|
||||
|
||||
public void Concat(params Object[] objects)
|
||||
|
@ -1351,12 +1429,7 @@ namespace System
|
|||
return -1;
|
||||
}
|
||||
|
||||
public bool Contains(String str)
|
||||
{
|
||||
return IndexOf(str) != -1;
|
||||
}
|
||||
|
||||
public bool Contains(String str, bool ignoreCase)
|
||||
public bool Contains(StringView str, bool ignoreCase = false)
|
||||
{
|
||||
return IndexOf(str, ignoreCase) != -1;
|
||||
}
|
||||
|
@ -1542,7 +1615,7 @@ namespace System
|
|||
mLength = newLength;
|
||||
}
|
||||
|
||||
public void Insert(int_strsize idx, char8 c)
|
||||
public void Insert(int idx, char8 c)
|
||||
{
|
||||
Contract.Requires(idx >= 0);
|
||||
|
||||
|
@ -1557,7 +1630,7 @@ namespace System
|
|||
mLength = newLength;
|
||||
}
|
||||
|
||||
public void Insert(int_strsize idx, char8 c, int count)
|
||||
public void Insert(int idx, char8 c, int count)
|
||||
{
|
||||
Contract.Requires(idx >= 0);
|
||||
|
||||
|
@ -1576,7 +1649,7 @@ namespace System
|
|||
mLength = newLength;
|
||||
}
|
||||
|
||||
public void Insert(int_strsize idx, char32 c)
|
||||
public void Insert(int idx, char32 c)
|
||||
{
|
||||
Contract.Requires(idx >= 0);
|
||||
|
||||
|
@ -1625,7 +1698,7 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
public void Insert(int_strsize idx, char32 c, int count)
|
||||
public void Insert(int idx, char32 c, int count)
|
||||
{
|
||||
Contract.Requires(idx >= 0);
|
||||
|
||||
|
@ -1700,7 +1773,7 @@ namespace System
|
|||
|
||||
//Contract.Assert((char8A | char8B) <= 0x7F, "strings have to be ASCII");
|
||||
|
||||
// uppercase both char8s - notice that we need just one compare per char8
|
||||
// uppercase both chars - notice that we need just one compare per char
|
||||
if ((uint32)(charA - 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
|
||||
if ((uint32)(charB - 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
|
||||
|
||||
|
@ -1708,7 +1781,7 @@ namespace System
|
|||
if (charA != charB)
|
||||
return false;
|
||||
|
||||
// Next char8
|
||||
// Next char
|
||||
curA++;curB++;
|
||||
curLength--;
|
||||
}
|
||||
|
@ -1733,7 +1806,7 @@ namespace System
|
|||
|
||||
//Contract.Assert((char8A | char8B) <= 0x7F, "strings have to be ASCII");
|
||||
|
||||
// uppercase both char8s - notice that we need just one compare per char8
|
||||
// uppercase both chars - notice that we need just one compare per char
|
||||
if ((uint32)(charA - 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
|
||||
if ((uint32)(charB - 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
|
||||
|
||||
|
@ -1741,7 +1814,7 @@ namespace System
|
|||
if (charA != charB)
|
||||
return charA - charB;
|
||||
|
||||
// Next char8
|
||||
// Next char
|
||||
a++;b++;
|
||||
length--;
|
||||
}
|
||||
|
@ -1761,7 +1834,7 @@ namespace System
|
|||
int_strsize charB = (int_strsize)*b;
|
||||
|
||||
//Contract.Assert((char8A | char8B) <= 0x7F, "strings have to be ASCII");
|
||||
// uppercase both char8s - notice that we need just one compare per char8
|
||||
// uppercase both chars - notice that we need just one compare per char
|
||||
if ((uint32)(charA - 'a') <= (uint32)('z' - 'a')) charA -= 0x20;
|
||||
if ((uint32)(charB - 'a') <= (uint32)('z' - 'a')) charB -= 0x20;
|
||||
|
||||
|
@ -1769,7 +1842,7 @@ namespace System
|
|||
if (charA != charB)
|
||||
return charA - charB;
|
||||
|
||||
// Next char8
|
||||
// Next char
|
||||
a++;b++;
|
||||
length--;
|
||||
}
|
||||
|
@ -2130,6 +2203,82 @@ namespace System
|
|||
TrimEnd();
|
||||
}
|
||||
|
||||
public void TrimEnd(char32 trimChar)
|
||||
{
|
||||
let ptr = Ptr;
|
||||
for (int i = mLength - 1; i >= 0; i--)
|
||||
{
|
||||
char8 c = ptr[i];
|
||||
if (c >= (char8)0x80)
|
||||
{
|
||||
var (c32, idx, len) = GetChar32WithBacktrack(i);
|
||||
if (c32 != trimChar)
|
||||
{
|
||||
if (i < mLength - 1)
|
||||
RemoveToEnd(i + 1);
|
||||
return;
|
||||
}
|
||||
i = idx;
|
||||
}
|
||||
else if ((char32)c != trimChar)
|
||||
{
|
||||
if (i < mLength - 1)
|
||||
RemoveToEnd(i + 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Clear();
|
||||
}
|
||||
|
||||
public void TrimEnd(char8 trimChar)
|
||||
{
|
||||
TrimEnd((char32)trimChar);
|
||||
}
|
||||
|
||||
public void TrimStart(char32 trimChar)
|
||||
{
|
||||
let ptr = Ptr;
|
||||
for (int i = 0; i < mLength; i++)
|
||||
{
|
||||
char8 c = ptr[i];
|
||||
if (c >= (char8)0x80)
|
||||
{
|
||||
var (c32, len) = GetChar32(i);
|
||||
if (c32 != trimChar)
|
||||
{
|
||||
if (i > 0)
|
||||
Remove(0, i);
|
||||
return;
|
||||
}
|
||||
i += len - 1;
|
||||
}
|
||||
else if ((char32)c != trimChar)
|
||||
{
|
||||
if (i > 0)
|
||||
Remove(0, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Clear();
|
||||
}
|
||||
|
||||
public void TrimStart(char8 trimChar)
|
||||
{
|
||||
TrimStart((char32)trimChar);
|
||||
}
|
||||
|
||||
public void Trim(char32 trimChar)
|
||||
{
|
||||
TrimStart(trimChar);
|
||||
TrimEnd(trimChar);
|
||||
}
|
||||
|
||||
public void Trim(char8 trimChar)
|
||||
{
|
||||
TrimStart((.)trimChar);
|
||||
TrimEnd((.)trimChar);
|
||||
}
|
||||
|
||||
public void Join(StringView sep, IEnumerator<String> enumerable)
|
||||
{
|
||||
bool isFirst = true;
|
||||
|
@ -2271,6 +2420,7 @@ namespace System
|
|||
|
||||
public RawEnumerator RawChars
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return RawEnumerator(Ptr, 0, mLength);
|
||||
|
@ -2279,6 +2429,7 @@ namespace System
|
|||
|
||||
public UTF8Enumerator DecodedChars
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return UTF8Enumerator(Ptr, 0, mLength);
|
||||
|
@ -2440,6 +2591,7 @@ namespace System
|
|||
int_strsize mIdx;
|
||||
int_strsize mLength;
|
||||
|
||||
[Inline]
|
||||
public this(char8* ptr, int idx, int length)
|
||||
{
|
||||
mPtr = ptr;
|
||||
|
@ -2449,11 +2601,13 @@ namespace System
|
|||
|
||||
public char8 Current
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mPtr[mIdx];
|
||||
}
|
||||
|
||||
[Inline]
|
||||
set
|
||||
{
|
||||
mPtr[mIdx] = value;
|
||||
|
@ -2462,6 +2616,7 @@ namespace System
|
|||
|
||||
public ref char8 CurrentRef
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return ref mPtr[mIdx];
|
||||
|
@ -2470,6 +2625,7 @@ namespace System
|
|||
|
||||
public int Index
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mIdx;
|
||||
|
@ -2478,42 +2634,29 @@ namespace System
|
|||
|
||||
public int Length
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return mLength;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool MoveNext() mut
|
||||
[Inline]
|
||||
public Result<char8> GetNext() mut
|
||||
{
|
||||
++mIdx;
|
||||
if (mIdx >= mLength)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Result<char8> GetNext() mut
|
||||
{
|
||||
if (!MoveNext())
|
||||
return .Err;
|
||||
return Current;
|
||||
return mPtr[mIdx];
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public Result<char8*> GetNextRef() mut
|
||||
{
|
||||
if (!MoveNext())
|
||||
++mIdx;
|
||||
if (mIdx >= mLength)
|
||||
return .Err;
|
||||
return &CurrentRef;
|
||||
return &mPtr[mIdx];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2669,6 +2812,14 @@ namespace System
|
|||
return mMatchPos;
|
||||
}
|
||||
}
|
||||
|
||||
public int32 MatchIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return mCurCount - 1;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasMore
|
||||
{
|
||||
|
@ -2821,6 +2972,97 @@ namespace System
|
|||
mLength = length;
|
||||
}
|
||||
|
||||
public ref char8 this[int index]
|
||||
{
|
||||
[Checked]
|
||||
get
|
||||
{
|
||||
Runtime.Assert((uint)index < (uint)mLength);
|
||||
return ref mPtr[index];
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
get
|
||||
{
|
||||
return ref mPtr[index];
|
||||
}
|
||||
}
|
||||
|
||||
public ref char8 this[Index index]
|
||||
{
|
||||
[Checked]
|
||||
get
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mLength - offset;
|
||||
}
|
||||
Runtime.Assert((uint)idx < (uint)mLength);
|
||||
return ref mPtr[idx];
|
||||
}
|
||||
|
||||
[Unchecked, Inline]
|
||||
get
|
||||
{
|
||||
int idx;
|
||||
switch (index)
|
||||
{
|
||||
case .FromFront(let offset): idx = offset;
|
||||
case .FromEnd(let offset): idx = mLength - offset;
|
||||
}
|
||||
return ref mPtr[idx];
|
||||
}
|
||||
}
|
||||
|
||||
public StringView this[IndexRange range]
|
||||
{
|
||||
#if !DEBUG
|
||||
[Inline]
|
||||
#endif
|
||||
get
|
||||
{
|
||||
char8* start;
|
||||
switch (range.[Friend]mStart)
|
||||
{
|
||||
case .FromFront(let offset):
|
||||
Debug.Assert((uint)offset <= (uint)mLength);
|
||||
start = mPtr + offset;
|
||||
case .FromEnd(let offset):
|
||||
Debug.Assert((uint)offset <= (uint)mLength);
|
||||
start = mPtr + mLength - offset;
|
||||
}
|
||||
char8* end;
|
||||
if (range.[Friend]mIsClosed)
|
||||
{
|
||||
switch (range.[Friend]mEnd)
|
||||
{
|
||||
case .FromFront(let offset):
|
||||
Debug.Assert((uint)offset < (uint)mLength);
|
||||
end = mPtr + offset + 1;
|
||||
case .FromEnd(let offset):
|
||||
Debug.Assert((uint)(offset - 1) <= (uint)mLength);
|
||||
end = mPtr + mLength - offset + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (range.[Friend]mEnd)
|
||||
{
|
||||
case .FromFront(let offset):
|
||||
Debug.Assert((uint)offset <= (uint)mLength);
|
||||
end = mPtr + offset;
|
||||
case .FromEnd(let offset):
|
||||
Debug.Assert((uint)offset <= (uint)mLength);
|
||||
end = mPtr + mLength - offset;
|
||||
}
|
||||
}
|
||||
|
||||
return .(start, end - start);
|
||||
}
|
||||
}
|
||||
|
||||
public String.RawEnumerator RawChars
|
||||
{
|
||||
get
|
||||
|
@ -2914,6 +3156,13 @@ namespace System
|
|||
return String.[Friend]CompareOrdinalHelper(val1.mPtr, val1.mLength, val2.mPtr, val2.mLength);
|
||||
}
|
||||
|
||||
public int CompareTo(StringView strB, bool ignoreCase = false)
|
||||
{
|
||||
if (ignoreCase)
|
||||
return String.[Friend]CompareOrdinalIgnoreCaseHelper(Ptr, Length, strB.Ptr, strB.Length);
|
||||
return String.[Friend]CompareOrdinalHelper(Ptr, Length, strB.Ptr, strB.Length);
|
||||
}
|
||||
|
||||
public bool Equals(StringView str)
|
||||
{
|
||||
if (mLength != str.[Friend]mLength)
|
||||
|
@ -3037,9 +3286,9 @@ namespace System
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool Contains(StringView stringView)
|
||||
public bool Contains(StringView stringView, bool ignoreCase = false)
|
||||
{
|
||||
return IndexOf(stringView) != -1;
|
||||
return IndexOf(stringView, ignoreCase) != -1;
|
||||
}
|
||||
|
||||
public bool StartsWith(StringView b, StringComparison comparisonType = StringComparison.Ordinal)
|
||||
|
@ -3130,6 +3379,92 @@ namespace System
|
|||
TrimEnd();
|
||||
}
|
||||
|
||||
public void TrimEnd(char32 trimChar) mut
|
||||
{
|
||||
let ptr = Ptr;
|
||||
for (int i = mLength - 1; i >= 0; i--)
|
||||
{
|
||||
char8 c = ptr[i];
|
||||
if (c >= (char8)0x80)
|
||||
{
|
||||
var (c32, idx, len) = GetChar32WithBacktrack(i);
|
||||
if (c32 != trimChar)
|
||||
{
|
||||
if (i < mLength - 1)
|
||||
{
|
||||
mLength = i + 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
i = idx;
|
||||
}
|
||||
else if (c != (char32)trimChar)
|
||||
{
|
||||
if (i < mLength - 1)
|
||||
{
|
||||
mLength = i + 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
Clear();
|
||||
}
|
||||
|
||||
public void TrimEnd(char8 trimChar) mut
|
||||
{
|
||||
TrimEnd((char32)trimChar);
|
||||
}
|
||||
|
||||
public void TrimStart(char32 trimChar) mut
|
||||
{
|
||||
let ptr = Ptr;
|
||||
for (int i = 0; i < mLength; i++)
|
||||
{
|
||||
char8 c = ptr[i];
|
||||
if (c >= (char8)0x80)
|
||||
{
|
||||
var (c32, len) = GetChar32(i);
|
||||
if (c32 != trimChar)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
mPtr += i;
|
||||
mLength -= i;
|
||||
}
|
||||
return;
|
||||
}
|
||||
i += len - 1;
|
||||
}
|
||||
else if (c != (char32)trimChar)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
mPtr += i;
|
||||
mLength -= i;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
Clear();
|
||||
}
|
||||
|
||||
public void TrimStart(char8 trimChar) mut
|
||||
{
|
||||
TrimStart((char32)trimChar);
|
||||
}
|
||||
|
||||
public void Trim(char32 trimChar) mut
|
||||
{
|
||||
TrimStart(trimChar);
|
||||
TrimEnd(trimChar);
|
||||
}
|
||||
|
||||
public void Trim(char8 trimChar) mut
|
||||
{
|
||||
TrimStart((.)trimChar);
|
||||
TrimEnd((.)trimChar);
|
||||
}
|
||||
|
||||
public bool StartsWith(char8 c)
|
||||
{
|
||||
if (mLength == 0)
|
||||
|
@ -3137,6 +3472,15 @@ namespace System
|
|||
return Ptr[0] == c;
|
||||
}
|
||||
|
||||
public bool StartsWith(char32 c)
|
||||
{
|
||||
if (c < '\x80')
|
||||
return StartsWith((char8)c);
|
||||
if (mLength == 0)
|
||||
return false;
|
||||
return UTF8.Decode(Ptr, mLength).c == c;
|
||||
}
|
||||
|
||||
public bool EndsWith(char8 c)
|
||||
{
|
||||
if (mLength == 0)
|
||||
|
@ -3144,6 +3488,19 @@ namespace System
|
|||
return Ptr[mLength - 1] == c;
|
||||
}
|
||||
|
||||
public bool EndsWith(char32 c)
|
||||
{
|
||||
if (c < '\x80')
|
||||
return EndsWith((char8)c);
|
||||
if (mLength == 0)
|
||||
return false;
|
||||
char8* ptr = Ptr;
|
||||
int idx = mLength - 1;
|
||||
while ((idx > 0) && ((uint8)ptr[idx] & 0xC0 == 0x80))
|
||||
idx--;
|
||||
return UTF8.Decode(ptr + idx, mLength - idx).c == c;
|
||||
}
|
||||
|
||||
public void QuoteString(String outString)
|
||||
{
|
||||
String.QuoteString(Ptr, Length, outString);
|
||||
|
@ -3226,6 +3583,34 @@ namespace System
|
|||
return StringSplitEnumerator(Ptr, Length, separators, count, options);
|
||||
}
|
||||
|
||||
public String Intern()
|
||||
{
|
||||
using (String.[Friend]sMonitor.Enter())
|
||||
{
|
||||
bool needsLiteralPass = String.[Friend]sInterns.Count == 0;
|
||||
String* internalLinkPtr = *((String**)(String.[Friend]sStringLiterals));
|
||||
if (internalLinkPtr != String.[Friend]sPrevInternLinkPtr)
|
||||
{
|
||||
String.[Friend]sPrevInternLinkPtr = internalLinkPtr;
|
||||
needsLiteralPass = true;
|
||||
}
|
||||
if (needsLiteralPass)
|
||||
String.[Friend]CheckLiterals(String.[Friend]sStringLiterals);
|
||||
|
||||
String* entryPtr;
|
||||
if (String.[Friend]sInterns.TryAddAlt(this, out entryPtr))
|
||||
{
|
||||
String result = new String(mLength + 1);
|
||||
result.Append(this);
|
||||
result.EnsureNullTerminator();
|
||||
*entryPtr = result;
|
||||
String.[Friend]sOwnedInterns.Add(result);
|
||||
return result;
|
||||
}
|
||||
return *entryPtr;
|
||||
}
|
||||
}
|
||||
|
||||
public static operator StringView (String str)
|
||||
{
|
||||
StringView sv;
|
||||
|
|
|
@ -227,6 +227,26 @@ static
|
|||
}
|
||||
}
|
||||
|
||||
public static mixin DeleteContainerAndDisposeItems(var container)
|
||||
{
|
||||
if (container != null)
|
||||
{
|
||||
for (var value in container)
|
||||
value.Dispose();
|
||||
delete container;
|
||||
}
|
||||
}
|
||||
|
||||
public static mixin ClearAndDisposeItems(var container)
|
||||
{
|
||||
if (container != null)
|
||||
{
|
||||
for (var value in container)
|
||||
value.Dispose();
|
||||
container.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static mixin DeleteAndNullify(var val)
|
||||
{
|
||||
delete val;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System.Diagnostics;
|
||||
namespace System.Text
|
||||
{
|
||||
[StaticInitPriority(100)]
|
||||
abstract class Encoding
|
||||
{
|
||||
public enum DecodeError
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System.Diagnostics;
|
||||
namespace System.Text
|
||||
{
|
||||
public class UTF16
|
||||
public static class UTF16
|
||||
{
|
||||
public enum EncodeError
|
||||
{
|
||||
|
@ -140,10 +140,10 @@ namespace System.Text
|
|||
|
||||
public static int GetMaxEncodedLen(int utf8Len)
|
||||
{
|
||||
// Consider all incoming char8s are < \u80, each incoming char88 equals one outgoing char816 (utfLen * 1)
|
||||
// For char8s from \u80 to \u7FF, then two incoming char88 equals one outgoing char816 (utfLen * 0.5)
|
||||
// For char8s from \u800 to \u7FFF, then three incoming char88 equals one or two char816s (utfLen * 0.33) to (utfLen * 0.67)
|
||||
// For char8s from \u1000 to \u10FFFF, then four incoming char88 equals two outgoing char816s (utfLen * 0.5)
|
||||
// Consider all incoming chars are < \u80, each incoming char8 equals one outgoing char16 (utfLen * 1)
|
||||
// For chars from \u80 to \u7FF, then two incoming char8 equals one outgoing char16 (utfLen * 0.5)
|
||||
// For chars from \u800 to \u7FFF, then three incoming char8 equals one or two char16s (utfLen * 0.33) to (utfLen * 0.67)
|
||||
// For chars from \u1000 to \u10FFFF, then four incoming char8 equals two outgoing char16s (utfLen * 0.5)
|
||||
return utf8Len;
|
||||
}
|
||||
|
||||
|
@ -211,7 +211,7 @@ namespace System.Text
|
|||
if (c <= '\u{FFFF}')
|
||||
{
|
||||
#if BF_UTF_PEDANTIC
|
||||
// Illegal UTF16 char8?
|
||||
// Illegal UTF16 char?
|
||||
Debug.Assert((c <= '\u{D7FF}') || (c >= '\u{E000}'));
|
||||
#endif
|
||||
EncodeChar((char16)c);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System.Diagnostics;
|
||||
namespace System.Text
|
||||
{
|
||||
class UTF8
|
||||
static class UTF8
|
||||
{
|
||||
public const int8[256] sTrailingBytesForUTF8 =
|
||||
.(
|
||||
|
|
|
@ -8,10 +8,11 @@ namespace System.Threading
|
|||
public delegate void ThreadStart();
|
||||
public delegate void ParameterizedThreadStart(Object obj);
|
||||
|
||||
[StaticInitPriority(100)]
|
||||
public sealed class Thread
|
||||
{
|
||||
private int mInternalThread;
|
||||
private int32 mPriority;
|
||||
private ThreadPriority mPriority = .Normal;
|
||||
public int32 mMaxStackSize;
|
||||
private String mName ~ delete _;
|
||||
private Delegate mDelegate;
|
||||
|
@ -21,7 +22,7 @@ namespace System.Threading
|
|||
bool mAutoDelete;
|
||||
public static Thread sMainThread = new Thread() ~ delete _;
|
||||
|
||||
[StaticInitPriority(101)]
|
||||
[StaticInitPriority(102)]
|
||||
struct RuntimeThreadInit
|
||||
{
|
||||
static Object Thread_Alloc()
|
||||
|
@ -67,6 +68,8 @@ namespace System.Threading
|
|||
|
||||
if (thread.mName != null)
|
||||
thread.InformThreadNameChange(thread.mName);
|
||||
if (thread.mPriority != .Normal)
|
||||
thread.SetPriorityNative((.)thread.mPriority);
|
||||
|
||||
int32 stackStart = 0;
|
||||
thread.SetStackStart((void*)&stackStart);
|
||||
|
@ -219,8 +222,18 @@ namespace System.Threading
|
|||
|
||||
public ThreadPriority Priority
|
||||
{
|
||||
get { return (ThreadPriority)GetPriorityNative(); }
|
||||
set { SetPriorityNative((int32)value); }
|
||||
get
|
||||
{
|
||||
if (mInternalThread != 0)
|
||||
return (ThreadPriority)GetPriorityNative();
|
||||
return mPriority;
|
||||
}
|
||||
set
|
||||
{
|
||||
mPriority = value;
|
||||
if (mInternalThread != 0)
|
||||
SetPriorityNative((int32)value);
|
||||
}
|
||||
}
|
||||
[CallingConvention(.Cdecl)]
|
||||
private extern int32 GetPriorityNative();
|
||||
|
|
|
@ -253,7 +253,10 @@ namespace System {
|
|||
if (rule != null)
|
||||
rule = rule.Clone();
|
||||
oneYearLocFromUtc = new OffsetAndRule(year, currentYear.BaseUtcOffset, rule);
|
||||
m_oneYearLocalFromUtc = oneYearLocFromUtc;
|
||||
if (Interlocked.CompareExchange(ref m_oneYearLocalFromUtc, null, oneYearLocFromUtc) != null) {
|
||||
delete oneYearLocFromUtc;
|
||||
oneYearLocFromUtc = m_oneYearLocalFromUtc;
|
||||
}
|
||||
}
|
||||
return oneYearLocFromUtc;
|
||||
}
|
||||
|
|
|
@ -20,13 +20,14 @@ namespace System
|
|||
|
||||
protected const BindingFlags cDefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
|
||||
|
||||
protected int32 mSize;
|
||||
protected TypeId mTypeId;
|
||||
protected TypeId mBoxedType;
|
||||
protected TypeFlags mTypeFlags;
|
||||
protected int32 mMemberDataOffset;
|
||||
protected TypeCode mTypeCode;
|
||||
protected uint8 mAlign;
|
||||
protected int32 mSize;
|
||||
protected TypeId mTypeId;
|
||||
protected TypeId mBoxedType;
|
||||
protected TypeFlags mTypeFlags;
|
||||
protected int32 mMemberDataOffset;
|
||||
protected TypeCode mTypeCode;
|
||||
protected uint8 mAlign;
|
||||
protected uint8 mAllocStackCountOverride;
|
||||
|
||||
public static TypeId TypeIdEnd
|
||||
{
|
||||
|
@ -683,13 +684,7 @@ namespace System
|
|||
|
||||
namespace System.Reflection
|
||||
{
|
||||
public struct TypeId : int32
|
||||
{
|
||||
public Type ToType()
|
||||
{
|
||||
return Type.[Friend]sTypes[(int32)this];
|
||||
}
|
||||
}
|
||||
public struct TypeId : int32 {}
|
||||
|
||||
[Ordered, AlwaysInclude(AssumeInstantiated=true)]
|
||||
public class TypeInstance : Type
|
||||
|
@ -724,6 +719,7 @@ namespace System.Reflection
|
|||
public int32 mMethodIdx;
|
||||
public int32 mVirtualIdx;
|
||||
public int32 mCustomAttributesIdx;
|
||||
public int32 mReturnCustomAttributesIdx;
|
||||
}
|
||||
|
||||
public enum ParamFlags : int16
|
||||
|
@ -740,6 +736,7 @@ namespace System.Reflection
|
|||
public TypeId mType;
|
||||
public ParamFlags mParamFlags;
|
||||
public int32 mDefaultIdx;
|
||||
public int32 mCustomAttributesIdx;
|
||||
}
|
||||
|
||||
public struct InterfaceData
|
||||
|
@ -1137,7 +1134,7 @@ namespace System.Reflection
|
|||
|
||||
public Type GetGenericArg(int argIdx)
|
||||
{
|
||||
return mResolvedTypeRefs[argIdx].ToType();
|
||||
return Type.GetType(mResolvedTypeRefs[argIdx]);
|
||||
}
|
||||
|
||||
public override void GetFullName(String strBuffer)
|
||||
|
@ -1191,7 +1188,10 @@ namespace System.Reflection
|
|||
let genericType = GetGenericArg(0);
|
||||
let arraySize = [Friend]mInstSize - genericType.Size + genericType.Stride * count;
|
||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||
obj = Internal.Dbg_ObjectAlloc([Friend]mTypeClassVData, arraySize, [Friend]mInstAlign, 1);
|
||||
int32 stackCount = Compiler.Options.AllocStackCount;
|
||||
if (mAllocStackCountOverride != 0)
|
||||
stackCount = mAllocStackCountOverride;
|
||||
obj = Internal.Dbg_ObjectAlloc([Friend]mTypeClassVData, arraySize, [Friend]mInstAlign, stackCount);
|
||||
#else
|
||||
void* mem = new [Align(16)] uint8[arraySize]* (?);
|
||||
obj = Internal.UnsafeCastToObject(mem);
|
||||
|
|
|
@ -48,8 +48,8 @@ namespace System
|
|||
public struct VTable
|
||||
{
|
||||
public function HResult(COM_IUnknown* self, ref Guid riid, void** result) QueryInterface;
|
||||
public function HResult(COM_IUnknown* self) AddRef;
|
||||
public function HResult(COM_IUnknown* self) Release;
|
||||
public function uint32(COM_IUnknown* self) AddRef;
|
||||
public function uint32(COM_IUnknown* self) Release;
|
||||
}
|
||||
|
||||
public enum HResult : int32
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue